tail: Fix -f with stdin

Based on a patch from swills@.

MFC after:	2 weeks
Differential Revision:	https://reviews.freebsd.org/D31113
This commit is contained in:
Mark Johnston 2021-07-08 17:40:59 -04:00
parent 02508a3d4e
commit 7e11889959
2 changed files with 21 additions and 24 deletions

View File

@ -56,7 +56,7 @@ struct mapinfo {
struct file_info { struct file_info {
FILE *fp; FILE *fp;
char *file_name; const char *file_name;
struct stat st; struct stat st;
}; };

View File

@ -67,8 +67,6 @@ static const char sccsid[] = "@(#)tail.c 8.1 (Berkeley) 6/6/93";
int Fflag, fflag, qflag, rflag, rval, no_files; int Fflag, fflag, qflag, rflag, rval, no_files;
fileargs_t *fa; fileargs_t *fa;
static file_info_t *files;
static void obsolete(char **); static void obsolete(char **);
static void usage(void); static void usage(void);
@ -88,8 +86,8 @@ main(int argc, char *argv[])
FILE *fp; FILE *fp;
off_t off; off_t off;
enum STYLE style; enum STYLE style;
int i, ch, first; int ch, first;
file_info_t *file; file_info_t file, *filep, *files;
char *p; char *p;
cap_rights_t rights; cap_rights_t rights;
@ -206,30 +204,24 @@ main(int argc, char *argv[])
} }
if (*argv && fflag) { if (*argv && fflag) {
files = (struct file_info *) malloc(no_files * files = malloc(no_files * sizeof(struct file_info));
sizeof(struct file_info)); if (files == NULL)
if (!files)
err(1, "Couldn't malloc space for file descriptors."); err(1, "Couldn't malloc space for file descriptors.");
for (file = files; (fn = *argv++); file++) { for (filep = files; (fn = *argv++); filep++) {
file->file_name = strdup(fn); filep->file_name = fn;
if (! file->file_name) filep->fp = fileargs_fopen(fa, filep->file_name, "r");
errx(1, "Couldn't malloc space for file name."); if (filep->fp == NULL ||
file->fp = fileargs_fopen(fa, file->file_name, "r"); fstat(fileno(filep->fp), &filep->st)) {
if (file->fp == NULL || if (filep->fp != NULL) {
fstat(fileno(file->fp), &file->st)) { fclose(filep->fp);
if (file->fp != NULL) { filep->fp = NULL;
fclose(file->fp);
file->fp = NULL;
} }
if (!Fflag || errno != ENOENT) if (!Fflag || errno != ENOENT)
ierr(file->file_name); ierr(filep->file_name);
} }
} }
follow(files, style, off); follow(files, style, off);
for (i = 0, file = files; i < no_files; i++, file++) {
free(file->file_name);
}
free(files); free(files);
} else if (*argv) { } else if (*argv) {
for (first = 1; (fn = *argv++);) { for (first = 1; (fn = *argv++);) {
@ -266,10 +258,15 @@ main(int argc, char *argv[])
fflag = 0; /* POSIX.2 requires this. */ fflag = 0; /* POSIX.2 requires this. */
} }
if (rflag) if (rflag) {
reverse(stdin, fn, style, off, &sb); reverse(stdin, fn, style, off, &sb);
else } else if (fflag) {
file.file_name = fn;
file.fp = stdin;
follow(&file, style, off);
} else {
forward(stdin, fn, style, off, &sb); forward(stdin, fn, style, off, &sb);
}
} }
fileargs_free(fa); fileargs_free(fa);
exit(rval); exit(rval);