diff options
author | Elliott Hughes <enh@google.com> | 2019-07-19 09:48:04 -0700 |
---|---|---|
committer | Rob Landley <rob@landley.net> | 2019-07-22 16:42:07 -0500 |
commit | b30674681b9d72430a029ba7bd3e16a3139244f0 (patch) | |
tree | f4b9b66e5c1537ea2a73d606f6b8aa3fe9e102c2 | |
parent | 43d398ad5d7b14fb344fc2e5338177761b9a199a (diff) | |
download | toybox-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.c | 9 | ||||
-rw-r--r-- | toys/other/rev.c | 26 | ||||
-rw-r--r-- | toys/posix/uudecode.c | 21 |
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); } } |