aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorElliott Hughes <enh@google.com>2019-07-19 09:48:04 -0700
committerRob Landley <rob@landley.net>2019-07-22 16:42:07 -0500
commitb30674681b9d72430a029ba7bd3e16a3139244f0 (patch)
treef4b9b66e5c1537ea2a73d606f6b8aa3fe9e102c2
parent43d398ad5d7b14fb344fc2e5338177761b9a199a (diff)
downloadtoybox-b30674681b9d72430a029ba7bd3e16a3139244f0.tar.gz
Start replacing get_line() with getline().
I started this last night, but thought I'd aim to send multiple small patches rather than work through all the callers and send one big patch. I've deliberately chosen the ugly name `allocated_length` because we've had historical bugs where folks think this a line length in the sense of the return value. I do wonder whether we should actually have some kind of getline() wrapper that hides the `char *`/`size_t` pair in lib/, which makes the function easier to use in most cases but does add the less common gotcha that you wouldn't be able to getline() through multiple files at once (which does happen in at least one toy). But maybe the real fix is to look harder for places where we can just use loopfiles_lines? Speaking of which, should we actually add two more arguments to that? Specifically: switch it to getdelim() rather than getline() behind the scenes, and also add a way to have the trailing '\n' automatically removed, since that seems to be what most callers want? Anyway, that seemed like enough questions that it was time to send this initial patch out before doing too much more...
-rw-r--r--lib/password.c9
-rw-r--r--toys/other/rev.c26
-rw-r--r--toys/posix/uudecode.c21
3 files changed, 30 insertions, 26 deletions
diff --git a/lib/password.c b/lib/password.c
index b9cc1346..432905cc 100644
--- a/lib/password.c
+++ b/lib/password.c
@@ -110,8 +110,9 @@ int update_password(char *filename, char* username, char* entry)
char *filenamesfx = NULL, *namesfx = NULL, *shadow = NULL,
*sfx = NULL, *line = NULL;
FILE *exfp, *newfp;
- int ret = -1, found = 0;
+ int ret = -1, found = 0, n;
struct flock lock;
+ size_t allocated_length;
shadow = strstr(filename, "shadow");
filenamesfx = xmprintf("%s+", filename);
@@ -149,8 +150,8 @@ int update_password(char *filename, char* username, char* entry)
ret = 0;
namesfx = xmprintf("%s:",username);
- while ((line = get_line(fileno(exfp))) != NULL)
- {
+ while ((n = getline(&line, &allocated_length, exfp)) > 0) {
+ line[n-1] = 0;
if (strncmp(line, namesfx, strlen(namesfx)))
fprintf(newfp, "%s\n", line);
else if (entry) {
@@ -175,8 +176,8 @@ int update_password(char *filename, char* username, char* entry)
fprintf(newfp, "%s\n", entry);
}
}
- free(line);
}
+ free(line);
free(namesfx);
if (!found && entry) fprintf(newfp, "%s\n", entry);
fcntl(fileno(exfp), F_SETLK, &lock);
diff --git a/toys/other/rev.c b/toys/other/rev.c
index 15066310..adfc90da 100644
--- a/toys/other/rev.c
+++ b/toys/other/rev.c
@@ -15,27 +15,25 @@ config REV
#include "toys.h"
-static void do_rev(int fd, char *name)
+static void rev_line(char **pline, long len)
{
- char *c;
+ char *line;
+ long i;
- for (;;) {
- unsigned len, i;
+ if (!pline) return;
+ line = *pline;
+ if (len && line[len-1]=='\n') line[--len] = 0;
- if (!(c = get_line(fd))) break;
- len = strlen(c);
- if (len--) for (i = 0; i <= len/2; i++) {
- char tmp = c[i];
+ if (len--) for (i = 0; i <= len/2; i++) {
+ char tmp = line[i];
- c[i] = c[len-i];
- c[len-i] = tmp;
- }
- xputs(c);
- free(c);
+ line[i] = line[len-i];
+ line[len-i] = tmp;
}
+ xputs(line);
}
void rev_main(void)
{
- loopfiles(toys.optargs, do_rev);
+ loopfiles_lines(toys.optargs, rev_line);
}
diff --git a/toys/posix/uudecode.c b/toys/posix/uudecode.c
index 220e43aa..4d87ce1c 100644
--- a/toys/posix/uudecode.c
+++ b/toys/posix/uudecode.c
@@ -26,15 +26,19 @@ GLOBALS(
void uudecode_main(void)
{
- int ifd = 0, ofd, idx = 0, m = m;
+ FILE *ifp = stdin;
+ int ofd, idx = 0, m = m, n;
+ size_t allocated_length;
char *line = 0, mode[16],
*class[] = {"begin%*[ ]%15s%*[ ]%n", "begin-base64%*[ ]%15s%*[ ]%n"};
- if (toys.optc) ifd = xopenro(*toys.optargs);
+ if (toys.optc) ifp = xfopen(*toys.optargs, "r");
while (!idx) {
- free(line);
- if (!(line = get_line(ifd))) error_exit("bad EOF");
+ if ((n = getline(&line, &allocated_length, ifp)) == -1)
+ error_exit("no begin line");
+ if (!n) continue;
+ line[n-1] = 0;
for (m=0; m < 2; m++) {
sscanf(line, class[m], mode, &idx);
if (idx) break;
@@ -45,12 +49,12 @@ void uudecode_main(void)
else ofd = xcreate(TT.o ? TT.o : line+idx, O_WRONLY|O_CREAT|O_TRUNC,
string_to_mode(mode, 0777^toys.old_umask));
- for(;;) {
+ for (;;) {
char *in, *out;
int olen;
- free(line);
- if (m == 2 || !(line = get_line(ifd))) break;
+ if (m == 2 || (n = getline(&line, &allocated_length, ifp)) == -1) break;
+ if (n) line[n-1] = 0;
if (!strcmp(line, m ? "====" : "end")) {
m = 2;
continue;
@@ -102,7 +106,8 @@ line_done:
}
if (CFG_TOYBOX_FREE) {
- if (ifd) close(ifd);
+ if (ifp != stdin) fclose(ifp);
close(ofd);
+ free(line);
}
}