sbase

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

commit c89a98ac0c90407f5b7f545f9ff696f2c0a236db
parent c0a932680e4172a0ac1a971d55153e7693f451dd
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)