sbase

suckless unix tools
git clone git://git.2f30.org/sbase
Log | Files | Refs | README | LICENSE

commit 286df29e7d78ae4a6b4474bb14d517e02e4f0489
parent 5d6e609455e04f4c6f5e633cb9eae21a9ef66718
Author: FRIGN <dev@frign.de>
Date:   Mon,  2 Mar 2015 14:19:26 +0100

Make already audited tools argv-centric instead of argc-centric

This has already been suggested by Evan Gates <evan.gates@gmail.com>
and he's totally right about it.
So, what's the problem?
I wrote a testing program asshole.c with

int
main(void)
{
        execl("/path/to/sbase/echo", "echo", "test");
        return 0;
}

and checked the results with glibc and musl. Note that the
sentinel NULL is missing from the end of the argument list.
glibc calculates an argc of 5, musl 4 (instead of 2) and thus
mess up things anyway.
The powerful arg.h also focuses on argv instead of argc as well,
but ignoring argc completely is also the wrong way to go.
Instead, a more idiomatic approach is to check *argv only and
decrement argc on the go.
While at it, I rewrote yes(1) in an argv-centric way as well.

All audited tools have been "fixed" and each following audited
tool will receive the same treatment.

Diffstat:
Mcat.c | 2+-
Mecho.c | 2+-
Mlibutil/crypt.c | 4++--
Mprintenv.c | 8++++----
Mrm.c | 4++--
Myes.c | 8++++----
6 files changed, 14 insertions(+), 14 deletions(-)

diff --git a/cat.c b/cat.c @@ -28,7 +28,7 @@ main(int argc, char *argv[]) if (argc == 0) { concat(stdin, "<stdin>", stdout, "<stdout>"); } else { - for (; argc > 0; argc--, argv++) { + for (; *argv; argc--, argv++) { if ((*argv)[0] == '-' && !(*argv)[1]) { concat(stdin, "<stdin>", stdout, "<stdout>"); } else if (!(fp = fopen(*argv, "r"))) { diff --git a/echo.c b/echo.c @@ -22,7 +22,7 @@ main(int argc, char *argv[]) usage(); } ARGEND; - for (; argc > 0; argc--, argv++) + for (; *argv; argc--, argv++) putword(*argv); if (!nflag) putchar('\n'); diff --git a/libutil/crypt.c b/libutil/crypt.c @@ -87,7 +87,7 @@ cryptcheck(int argc, char *argv[], struct crypt_ops *ops, uint8_t *md, size_t sz if (argc == 0) { mdchecklist(stdin, ops, md, sz, &formatsucks, &noread, &nonmatch); } else { - for (; argc > 0; argc--, argv++) { + for (; *argv; argc--, argv++) { if (!(fp = fopen(*argv, "r"))) { weprintf("fopen %s:", *argv); ret = 1; @@ -124,7 +124,7 @@ cryptmain(int argc, char *argv[], struct crypt_ops *ops, uint8_t *md, size_t sz) cryptsum(ops, stdin, "<stdin>", md); mdprint(md, "<stdin>", sz); } else { - for (; argc > 0; argc--, argv++) { + for (; *argv; argc--, argv++) { if (!(fp = fopen(*argv, "r"))) { weprintf("fopen %s:", *argv); ret = 1; diff --git a/printenv.c b/printenv.c @@ -24,12 +24,12 @@ main(int argc, char *argv[]) } ARGEND; if (!argc) { - while (*environ) - printf("%s\n", *environ++); + for (; *environ; environ++) + puts(*environ); } else { - for (; argc > 0; argc--, argv++) { + for (; *argv; argc--, argv++) { if ((var = getenv(*argv))) - printf("%s\n", var); + puts(var); else ret = 1; } diff --git a/rm.c b/rm.c @@ -30,8 +30,8 @@ main(int argc, char *argv[]) return 0; } - for (; argc > 0; argc--, argv++) - rm(argv[0], 0); + for (; *argv; argc--, argv++) + rm(*argv, 0); return rm_status; } diff --git a/yes.c b/yes.c @@ -12,16 +12,16 @@ usage(void) int main(int argc, char *argv[]) { - size_t i; + char **p; ARGBEGIN { default: usage(); } ARGEND; - for (i = 0; ; i++, i %= argc ? argc : 1) { - fputs(argc ? argv[i] : "y", stdout); - putchar((!argc || i == argc - 1) ? '\n' : ' '); + for (p = argv; ; p = (*p && *(p + 1)) ? p + 1 : argv) { + fputs(*p ? *p : "y", stdout); + putchar((!*p || !*(p + 1)) ? '\n' : ' '); } return 1; /* not reached */