sbase

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

commit 0545d32ce98dd8a9eeafe829e227b9a779383aa0
parent 6be7eaff1b07845aa80b3bba8bc4de48b2305146
Author: FRIGN <dev@frign.de>
Date:   Fri May 15 13:28:39 +0200

Handle '-' consistently

In general, POSIX does not define /dev/std{in, out, err} because it
does not want to depend on the dev-filesystem.
For utilities, it thus introduced the '-'-keyword to denote standard
input (and output in some cases) and the programs have to deal with
it accordingly.

Sadly, the design of many tools doesn't allow strict shell-redirections
and many scripts don't even use this feature when possible.

Thus, we made the decision to implement it consistently across all
tools where it makes sense (namely those which read files).

Along the way, I spotted some behavioural bugs in libutil/crypt.c and
others where it was forgotten to fshut the files after use.

Diffstat:
cat.c | 12++++++------
cksum.c | 10++++++----
cols.c | 7+++++--
cut.c | 21++++++++++-----------
expand.c | 7+++++--
fold.c | 13++++++++-----
grep.c | 13++++++++-----
head.c | 9++++++---
join.c | 2+-
libutil/crypt.c | 14++++++++++----
nl.c | 10+++++++---
paste.c | 5+++--
sed.c | 3++-
sort.c | 7+++++--
strings.c | 7+++++--
tail.c | 9++++++---
unexpand.c | 9+++++++--
uniq.c | 21++++++++++++++-------
uudecode.c | 2+-
uuencode.c | 2+-
wc.c | 7+++++--
21 files changed, 121 insertions(+), 69 deletions(-)
diff --git a/cat.c b/cat.c @@ -30,16 +30,16 @@ main(int argc, char *argv[]) } else { for (; *argv; argc--, argv++) { if ((*argv)[0] == '-' && !(*argv)[1]) { - concat(stdin, "<stdin>", stdout, "<stdout>"); + *argv = "<stdin>"; + fp = stdin; } else if (!(fp = fopen(*argv, "r"))) { weprintf("fopen %s:", *argv); ret = 1; - } else { - concat(fp, *argv, stdout, "<stdout>"); - if (fshut(fp, *argv)) { - ret = 1; - } + continue; } + concat(fp, *argv, stdout, "<stdout>"); + if (fp != stdin && fshut(fp, *argv)) + ret = 1; } } diff --git a/cksum.c b/cksum.c @@ -96,17 +96,19 @@ main(int argc, char *argv[]) cksum(stdin, NULL); } else { for (; *argv; argc--, argv++) { - if (!(fp = fopen(*argv, "r"))) { + if ((*argv)[0] == '-' && !(*argv)[1]) { + *argv = "<stdin>"; + fp = stdin; + } else if (!(fp = fopen(*argv, "r"))) { weprintf("fopen %s:", *argv); ret = 1; continue; } cksum(fp, *argv); - if (fshut(fp, *argv)) { + if (fp != stdin && fshut(fp, *argv)) ret = 1; - } } } - return fshut(stdout, "<stdout>") || ret; + return !!(fshut(stdin, "<stdin>") + fshut(stdout, "<stdout>")) || ret; } diff --git a/cols.c b/cols.c @@ -48,13 +48,16 @@ main(int argc, char *argv[]) getlines(stdin, &b); } else { for (; *argv; argc--, argv++) { - if (!(fp = fopen(*argv, "r"))) { + if ((*argv)[0] == '-' && !(*argv)[1]) { + *argv = "<stdin>"; + fp = stdin; + } else if (!(fp = fopen(*argv, "r"))) { weprintf("fopen %s:", *argv); ret = 1; continue; } getlines(fp, &b); - if (fshut(fp, *argv)) + if (fp != stdin && fshut(fp, *argv)) ret = 1; } } diff --git a/cut.c b/cut.c @@ -187,18 +187,17 @@ main(int argc, char *argv[]) cut(stdin, "<stdin>"); else { for (; *argv; argc--, argv++) { - if (*argv[0] == '-' && !*argv[1]) { - cut(stdin, "<stdin>"); - } else { - if (!(fp = fopen(*argv, "r"))) { - weprintf("fopen %s:", *argv); - ret = 1; - continue; - } - cut(fp, *argv); - if (fshut(fp, *argv)) - ret = 1; + if ((*argv)[0] == '-' && !(*argv)[1]) { + *argv = "<stdin>"; + fp = stdin; + } else if (!(fp = fopen(*argv, "r"))) { + weprintf("fopen %s:", *argv); + ret = 1; + continue; } + cut(fp, *argv); + if (fp != stdin && fshut(fp, *argv)) + ret = 1; } } diff --git a/expand.c b/expand.c @@ -110,13 +110,16 @@ main(int argc, char *argv[]) expand("<stdin>", stdin); } else { for (; *argv; argc--, argv++) { - if (!(fp = fopen(*argv, "r"))) { + if ((*argv)[0] == '-' && !(*argv)[1]) { + *argv = "<stdin>"; + fp = stdin; + } else if (!(fp = fopen(*argv, "r"))) { weprintf("fopen %s:", *argv); ret = 1; continue; } expand(*argv, fp); - if (fshut(fp, *argv)) + if (fp != stdin && fshut(fp, *argv)) ret = 1; } } diff --git a/fold.c b/fold.c @@ -95,14 +95,17 @@ main(int argc, char *argv[]) fold(stdin, "<stdin>"); } else { for (; *argv; argc--, argv++) { - if (!(fp = fopen(*argv, "r"))) { + if ((*argv)[0] == '-' && !(*argv)[1]) { + *argv = "<stdin>"; + fp = stdin; + } else if (!(fp = fopen(*argv, "r"))) { weprintf("fopen %s:", *argv); ret = 1; - } else { - fold(fp, *argv); - if (fshut(fp, *argv)) - ret = 1; + continue; } + fold(fp, *argv); + if (fp != stdin && fshut(fp, *argv)) + ret = 1; } } diff --git a/grep.c b/grep.c @@ -259,17 +259,20 @@ main(int argc, char *argv[]) if (argc == 0) { match = grep(stdin, "<stdin>"); } else { - for (i = 0; i < argc; i++) { - if (!(fp = fopen(argv[i], "r"))) { + for (; *argv; argc--, argv++) { + if ((*argv)[0] == '-' && !(*argv)[1]) { + *argv = "<stdin>"; + fp = stdin; + } else if (!(fp = fopen(*argv, "r"))) { if (!sflag) - weprintf("fopen %s:", argv[i]); + weprintf("fopen %s:", *argv); match = Error; continue; } - m = grep(fp, argv[i]); + m = grep(fp, *argv); if (m == Error || (match != Error && m == Match)) match = m; - if (fshut(fp, argv[i])) + if (fp != stdin && fshut(fp, *argv)) match = Error; } } diff --git a/head.c b/head.c @@ -32,7 +32,7 @@ main(int argc, char *argv[]) { size_t n = 10; FILE *fp; - int ret = 0, newline, many; + int ret = 0, newline = 0, many = 0; ARGBEGIN { case 'n': @@ -50,7 +50,10 @@ main(int argc, char *argv[]) } else { many = argc > 1; for (newline = 0; *argv; argc--, argv++) { - if (!(fp = fopen(*argv, "r"))) { + if ((*argv)[0] == '-' && !(*argv)[1]) { + *argv = "<stdin>"; + fp = stdin; + } else if (!(fp = fopen(*argv, "r"))) { weprintf("fopen %s:", *argv); ret = 1; continue; @@ -62,7 +65,7 @@ main(int argc, char *argv[]) } newline = 1; head(fp, *argv, n); - if(fshut(fp, *argv)) + if (fp != stdin && fshut(fp, *argv)) ret = 1; } } diff --git a/join.c b/join.c @@ -548,5 +548,5 @@ main(int argc, char *argv[]) if (fp[0] != fp[1]) enfshut(2, fp[1], argv[1]); enfshut(2, stdout, "<stdout>"); - exit(0); + return 0; } diff --git a/libutil/crypt.c b/libutil/crypt.c @@ -126,18 +126,24 @@ cryptmain(int argc, char *argv[], struct crypt_ops *ops, uint8_t *md, size_t sz) mdprint(md, "<stdin>", sz); } else { for (; *argv; argc--, argv++) { - if (!(fp = fopen(*argv, "r"))) { + if ((*argv)[0] == '-' && !(*argv)[1]) { + *argv = "<stdin>"; + fp = stdin; + } else if (!(fp = fopen(*argv, "r"))) { weprintf("fopen %s:", *argv); ret = 1; continue; } - if (cryptsum(ops, fp, *argv, md) == 1) + if (cryptsum(ops, fp, *argv, md)) { ret = 1; - else + } else { mdprint(md, *argv, sz); - fclose(fp); + } + if (fp != stdin && fshut(fp, *argv)) + ret = 1; } } + return ret; } diff --git a/nl.c b/nl.c @@ -190,11 +190,15 @@ main(int argc, char *argv[]) if (!argc) { nl("<stdin>", stdin); } else { - if (!(fp = fopen(argv[0], "r"))) + if (argv[0][0] == '-' && !argv[0][1]) { + argv[0] = "<stdin>"; + fp = stdin; + } else if (!(fp = fopen(argv[0], "r"))) { eprintf("fopen %s:", argv[0]); + } nl(argv[0], fp); } - return !!((fp && fshut(fp, argv[0])) + fshut(stdin, "<stdin>") + - fshut(stdout, "<stdout>")); + return !!((fp && fp != stdin && fshut(fp, argv[0])) + + fshut(stdin, "<stdin>") + fshut(stdout, "<stdout>")); } diff --git a/paste.c b/paste.c @@ -116,7 +116,8 @@ main(int argc, char *argv[]) dsc = ereallocarray(NULL, argc, sizeof(*dsc)); for (i = 0; i < argc; i++) { - if (!strcmp(argv[i], "-")) { + if (argv[i][0] == '-' && !argv[i][1]) { + argv[i] = "<stdin>"; dsc[i].fp = stdin; } else if (!(dsc[i].fp = fopen(argv[i], "r"))) { eprintf("fopen %s:", argv[i]); @@ -134,5 +135,5 @@ main(int argc, char *argv[]) if (dsc[i].fp != stdin && fshut(dsc[i].fp, argv[i])) ret = 1; - return fshut(stdin, "<stdin>") || fshut(stdout, "<stdout>") || ret; + return !!(fshut(stdin, "<stdin>") + fshut(stdout, "<stdout>")) || ret; } diff --git a/sed.c b/sed.c @@ -1114,7 +1114,7 @@ next_file(void) if (first) /* given no files, default to stdin */ file = stdin; /* else we've used all our files, leave file = NULL */ - } else if (!strcmp(*files, "-")) { + } else if ((*files)[0] == '-' && !(*files)[1]) { file = stdin; files++; } else if (!(file = fopen(*files++, "r"))) { @@ -1123,6 +1123,7 @@ next_file(void) } } while (!file && *files); first = 0; + return !file; } diff --git a/sort.c b/sort.c @@ -301,7 +301,10 @@ main(int argc, char *argv[]) getlines(stdin, &linebuf); } } else for (; *argv; argc--, argv++) { - if (!(fp = fopen(*argv, "r"))) { + if ((*argv)[0] == '-' && !(*argv)[1]) { + *argv = "<stdin>"; + fp = stdin; + } else if (!(fp = fopen(*argv, "r"))) { enprintf(2, "fopen %s:", *argv); continue; } @@ -310,7 +313,7 @@ main(int argc, char *argv[]) } else { getlines(fp, &linebuf); } - if (fshut(fp, *argv)) + if (fp != stdin && fshut(fp, *argv)) ret = 1; } diff --git a/strings.c b/strings.c @@ -79,13 +79,16 @@ main(int argc, char *argv[]) strings(stdin, "<stdin>", len); } else { for (; *argv; argc--, argv++) { - if (!(fp = fopen(*argv, "r"))) { + if ((*argv)[0] == '-' && !(*argv)[1]) { + *argv = "<stdin>"; + fp = stdin; + } else if (!(fp = fopen(*argv, "r"))) { weprintf("fopen %s:", *argv); ret = 1; continue; } strings(fp, *argv, len); - if (fshut(fp, *argv)) + if (fp != stdin && fshut(fp, *argv)) ret = 1; } } diff --git a/tail.c b/tail.c @@ -83,7 +83,7 @@ main(int argc, char *argv[]) struct stat st1, st2; FILE *fp; size_t tmpsize; - int ret = 0, newline, many; + int ret = 0, newline = 0, many = 0; char *numstr, *tmp; void (*tail)(FILE *, const char *) = taketail; @@ -115,7 +115,10 @@ main(int argc, char *argv[]) if ((many = argc > 1) && fflag) usage(); for (newline = 0; *argv; argc--, argv++) { - if (!(fp = fopen(*argv, "r"))) { + if ((*argv)[0] == '-' && !(*argv)[1]) { + *argv = "<stdin>"; + fp = stdin; + } else if (!(fp = fopen(*argv, "r"))) { weprintf("fopen %s:", *argv); ret = 1; continue; @@ -130,7 +133,7 @@ main(int argc, char *argv[]) tail(fp, *argv); if (!fflag) { - if (fshut(fp, *argv)) + if (fp != stdin && fshut(fp, *argv)) ret = 1; continue; } diff --git a/unexpand.c b/unexpand.c @@ -153,16 +153,21 @@ main(int argc, char *argv[]) unexpand("<stdin>", stdin); } else { for (; *argv; argc--, argv++) { - if (!(fp = fopen(*argv, "r"))) { + if ((*argv)[0] == '-' && !(*argv)[1]) { + *argv = "<stdin>"; + fp = stdin; + } else if (!(fp = fopen(*argv, "r"))) { weprintf("fopen %s:", *argv); ret = 1; continue; } unexpand(*argv, fp); - if (fshut(fp, *argv)) + if (fp != stdin && fshut(fp, *argv)) ret = 1; } } + efshut(stdin, "<stdin>"); + efshut(stdout, "<stdout>"); return ret; } diff --git a/uniq.c b/uniq.c @@ -96,7 +96,7 @@ usage(void) int main(int argc, char *argv[]) { - FILE *fp = stdin, *ofp = stdout; + FILE *fp, *ofp; ARGBEGIN { case 'c': @@ -124,16 +124,23 @@ main(int argc, char *argv[]) if (!argc) { uniq(stdin, stdout); } else { - if (strcmp(argv[0], "-") && !(fp = fopen(argv[0], "r"))) + if (argv[0][0] == '-' && !argv[0][1]) { + argv[0] = "<stdin>"; + fp = stdin; + } else if (!(fp = fopen(argv[0], "r"))) { eprintf("fopen %s:", argv[0]); - if (argc == 2) { - if (strcmp(argv[1], "-") && !(ofp = fopen(argv[1], "w"))) - eprintf("fopen %s:", argv[1]); + } + if (argc == 1 || (argv[1][0] == '-' && !argv[1][1])) { + argv[1] = "<stdout>"; + ofp = stdout; + } else if (!(ofp = fopen(argv[1], "w"))) { + eprintf("fopen %s:", argv[1]); } uniq(fp, ofp); } uniqfinish(ofp); - return !!(fshut(fp, fp == stdin ? "<stdin>" : argv[0]) + - fshut(ofp, ofp == stdout ? "<stdout>" : argv[1])); + efshut(fp, argv[0]); + efshut(ofp, argv[1]); + return 0; } diff --git a/uudecode.c b/uudecode.c @@ -246,7 +246,7 @@ main(int argc, char *argv[]) if (argc > 1) usage(); - if (!argc) { + if (!argc || (argv[0][0] == '-' && !argv[0][1])) { fp = stdin; ifname = "<stdin>"; } else { diff --git a/uuencode.c b/uuencode.c @@ -114,7 +114,7 @@ main(int argc, char *argv[]) if (!argc || argc > 2) usage(); - if (argc == 1) { + if (argc == 1 || (argv[0][0] == '-' && !argv[0][1])) { if (mflag) uuencodeb64(stdin, argv[0], "<stdin>"); else diff --git a/wc.c b/wc.c @@ -84,13 +84,16 @@ main(int argc, char *argv[]) wc(stdin, NULL); } else { for (many = (argc > 1); *argv; argc--, argv++) { - if (!(fp = fopen(*argv, "r"))) { + if ((*argv)[0] == '-' && !(*argv)[1]) { + *argv = "<stdin>"; + fp = stdin; + } else if (!(fp = fopen(*argv, "r"))) { weprintf("fopen %s:", *argv); ret = 1; continue; } wc(fp, *argv); - if (fshut(fp, *argv)) + if (fp != stdin && fshut(fp, *argv)) ret = 1; } if (many)