Audit tail(1)

1) Specify default in manpage under flag.
2) Boolean and return value style fixes.
3) argv-argc-centric loop.
4) No need to check for argc == 1 before the fflag-subroutine.
5) Remove indentation.
6) Empty line before return.
This commit is contained in:
FRIGN 2015-03-17 23:24:43 +01:00
parent 3c5d0ce4ca
commit 6372a8f227
3 changed files with 35 additions and 36 deletions

2
README
View File

@ -71,7 +71,7 @@ The following tools are implemented ('*' == finished, '#' == UTF-8 support,
=*| sponge non-posix none =*| sponge non-posix none
#*| strings yes none #*| strings yes none
=*| 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

4
tail.1
View File

@ -1,4 +1,4 @@
.Dd March 5, 2015 .Dd March 17, 2015
.Dt TAIL 1 .Dt TAIL 1
.Os sbase .Os sbase
.Sh NAME .Sh NAME
@ -31,7 +31,7 @@ it is an offset from the beginning of each
.Ar file . .Ar file .
If If
.Ar num .Ar num
begins with '-' it is as if no sign was given. begins with '-' it is as if no sign was given. The default is 10 lines.
.It Fl f .It Fl f
If one If one
.Ar file .Ar file

39
tail.c
View File

@ -24,7 +24,7 @@ dropinit(FILE *fp, const char *str)
ssize_t len; ssize_t len;
if (mode == 'n') { if (mode == 'n') {
while (i < num && (len = getline(&buf, &size, fp)) != -1) while (i < num && (len = getline(&buf, &size, fp)) >= 0)
if (len > 0 && buf[len - 1] == '\n') if (len > 0 && buf[len - 1] == '\n')
i++; i++;
} else { } else {
@ -106,43 +106,43 @@ main(int argc, char *argv[])
usage(); usage();
} ARGEND; } ARGEND;
if (argc == 0) if (!argc)
tail(stdin, "<stdin>"); tail(stdin, "<stdin>");
else { else {
if ((many = argc > 1) && fflag) if ((many = argc > 1) && fflag)
usage(); usage();
for (newline = 0; argc > 0; argc--, argv++) { for (newline = 0; *argv; argc--, argv++) {
if (!(fp = fopen(argv[0], "r"))) { if (!(fp = fopen(*argv, "r"))) {
weprintf("fopen %s:", argv[0]); weprintf("fopen %s:", *argv);
ret = 1; ret = 1;
continue; continue;
} }
if (many) if (many)
printf("%s==> %s <==\n", printf("%s==> %s <==\n", newline ? "\n" : "", *argv);
newline ? "\n" : "", argv[0]); if (stat(*argv, &st1) < 0)
if (stat(argv[0], &st1) < 0) eprintf("stat %s:", *argv);
eprintf("stat %s:", argv[0]);
if (!(S_ISFIFO(st1.st_mode) || S_ISREG(st1.st_mode))) if (!(S_ISFIFO(st1.st_mode) || S_ISREG(st1.st_mode)))
fflag = 0; fflag = 0;
newline = 1; newline = 1;
tail(fp, argv[0]); tail(fp, *argv);
if (fflag && argc == 1) { if (!fflag) {
tmp = NULL; fclose(fp);
tmpsize = 0; continue;
for (;;) { }
while (getline(&tmp, &tmpsize, fp) != -1) { for (tmp = NULL, tmpsize = 0;;) {
while (getline(&tmp, &tmpsize, fp) >= 0) {
fputs(tmp, stdout); fputs(tmp, stdout);
fflush(stdout); fflush(stdout);
} }
if (ferror(fp)) if (ferror(fp))
eprintf("readline %s:", argv[0]); eprintf("readline %s:", *argv);
clearerr(fp); clearerr(fp);
/* ignore error in case file was removed, we continue /* ignore error in case file was removed, we continue
* tracking the existing open file descriptor */ * tracking the existing open file descriptor */
if (!stat(argv[0], &st2)) { if (!stat(*argv, &st2)) {
if (st2.st_size < st1.st_size) { if (st2.st_size < st1.st_size) {
fprintf(stderr, "%s: file truncated\n", argv[0]); fprintf(stderr, "%s: file truncated\n", *argv);
rewind(fp); rewind(fp);
} }
st1 = st2; st1 = st2;
@ -150,8 +150,7 @@ main(int argc, char *argv[])
sleep(1); sleep(1);
} }
} }
fclose(fp);
}
} }
return ret; return ret;
} }