Audit tee(1)
1) "duplicate" implies that you can only specify two outputs, "multiply" is a better word describing the functionality. 2) fix other wording in the manpage 3) fix usage() 4) reorder local variables 5) fix sizeof() style 6) we need argv later, don't increment argv and rather iterate over argc. 7) Improve error messages, print the filename which the write failed to instead of printing the buffer itself (how much sense does that make, printing 1024 Bytes of garbage?). Also, give the name of the function which failed.
This commit is contained in:
parent
2fa6dc8159
commit
aaac1c8800
2
README
2
README
|
@ -73,7 +73,7 @@ The following tools are implemented ('*' == finished, '#' == UTF-8 support,
|
||||||
=* sync non-posix none
|
=* sync non-posix none
|
||||||
=* tail yes none
|
=* tail yes none
|
||||||
=* tar non-posix none
|
=* tar non-posix none
|
||||||
=* tee yes none
|
=*| tee yes none
|
||||||
=* test yes none
|
=* test yes none
|
||||||
= time yes none
|
= time yes none
|
||||||
=* touch yes none
|
=* touch yes none
|
||||||
|
|
6
tee.1
6
tee.1
|
@ -1,16 +1,16 @@
|
||||||
.Dd January 23, 2015
|
.Dd March 4, 2015
|
||||||
.Dt TEE 1
|
.Dt TEE 1
|
||||||
.Os sbase
|
.Os sbase
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
.Nm tee
|
.Nm tee
|
||||||
.Nd duplicate stdin
|
.Nd multiply stdin
|
||||||
.Sh SYNOPSIS
|
.Sh SYNOPSIS
|
||||||
.Nm
|
.Nm
|
||||||
.Op Fl ai
|
.Op Fl ai
|
||||||
.Op Ar file ...
|
.Op Ar file ...
|
||||||
.Sh DESCRIPTION
|
.Sh DESCRIPTION
|
||||||
.Nm
|
.Nm
|
||||||
writes from stdin to stdout and each
|
reads from stdin and writes to stdout and each
|
||||||
.Ar file .
|
.Ar file .
|
||||||
.Sh OPTIONS
|
.Sh OPTIONS
|
||||||
.Bl -tag -width Ds
|
.Bl -tag -width Ds
|
||||||
|
|
24
tee.c
24
tee.c
|
@ -7,17 +7,16 @@
|
||||||
static void
|
static void
|
||||||
usage(void)
|
usage(void)
|
||||||
{
|
{
|
||||||
eprintf("usage: %s [-ai] [file...]\n", argv0);
|
eprintf("usage: %s [-ai] [file ...]\n", argv0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
main(int argc, char *argv[])
|
main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
|
FILE **fps = NULL;
|
||||||
|
size_t i, n, nfps;
|
||||||
int aflag = 0, iflag = 0;
|
int aflag = 0, iflag = 0;
|
||||||
char buf[BUFSIZ];
|
char buf[BUFSIZ];
|
||||||
int i, nfps;
|
|
||||||
size_t n;
|
|
||||||
FILE **fps = NULL;
|
|
||||||
|
|
||||||
ARGBEGIN {
|
ARGBEGIN {
|
||||||
case 'a':
|
case 'a':
|
||||||
|
@ -33,21 +32,22 @@ main(int argc, char *argv[])
|
||||||
if (iflag && signal(SIGINT, SIG_IGN) == SIG_ERR)
|
if (iflag && signal(SIGINT, SIG_IGN) == SIG_ERR)
|
||||||
eprintf("signal:");
|
eprintf("signal:");
|
||||||
nfps = argc + 1;
|
nfps = argc + 1;
|
||||||
fps = ecalloc(nfps, sizeof *fps);
|
fps = ecalloc(nfps, sizeof(*fps));
|
||||||
|
|
||||||
for (i = 0; argc > 0; argc--, argv++, i++)
|
for (i = 0; i < argc; i++)
|
||||||
if (!(fps[i] = fopen(*argv, aflag ? "a" : "w")))
|
if (!(fps[i] = fopen(argv[i], aflag ? "a" : "w")))
|
||||||
eprintf("fopen %s:", *argv);
|
eprintf("fopen %s:", argv[i]);
|
||||||
fps[i] = stdout;
|
fps[i] = stdout;
|
||||||
|
|
||||||
while ((n = fread(buf, 1, sizeof buf, stdin)) > 0) {
|
while ((n = fread(buf, 1, sizeof(buf), stdin))) {
|
||||||
for (i = 0; i < nfps; i++) {
|
for (i = 0; i < nfps; i++) {
|
||||||
if (fwrite(buf, 1, n, fps[i]) != n)
|
if (fwrite(buf, 1, n, fps[i]) == n)
|
||||||
eprintf("%s: write error:", buf);
|
continue;
|
||||||
|
eprintf("fwrite %s:", (i != argc) ? argv[i] : "<stdout>");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (ferror(stdin))
|
if (ferror(stdin))
|
||||||
eprintf("<stdin>: read error:");
|
eprintf("fread <stdin>:");
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user