diff options
| author | Dag-Erling Smørgrav <des@FreeBSD.org> | 2023-11-29 21:48:50 +0000 |
|---|---|---|
| committer | Dag-Erling Smørgrav <des@FreeBSD.org> | 2023-11-29 21:49:38 +0000 |
| commit | 621f45532c5887c96b708ce232c52878d0053325 (patch) | |
| tree | 00ed1d1ce1fb47b1a7238f537320efbaf04b5a2a | |
| parent | b647615ede46af66cd0c8bd5a321d4a2cccdabe0 (diff) | |
| -rw-r--r-- | usr.bin/tail/forward.c | 39 | ||||
| -rwxr-xr-x | usr.bin/tail/tests/tail_test.sh | 21 |
2 files changed, 38 insertions, 22 deletions
diff --git a/usr.bin/tail/forward.c b/usr.bin/tail/forward.c index e8e2cb89ab01..a8f52ed376c4 100644 --- a/usr.bin/tail/forward.c +++ b/usr.bin/tail/forward.c @@ -272,7 +272,7 @@ set_events(file_info_t *files) action = USE_KQUEUE; for (i = 0, file = files; i < no_files; i++, file++) { - if (! file->fp) + if (!file->fp) continue; if (fstatfs(fileno(file->fp), &sf) == 0 && @@ -304,27 +304,21 @@ set_events(file_info_t *files) void follow(file_info_t *files, enum STYLE style, off_t off) { - int active, ev_change, i, n = -1; + int active, ev_change, i, n; struct stat sb2; file_info_t *file; FILE *ftmp; struct timespec ts; /* Position each of the files */ - - file = files; active = 0; - n = 0; - for (i = 0; i < no_files; i++, file++) { - if (file->fp) { - active = 1; - n++; - if (vflag || (qflag == 0 && no_files > 1)) - printfn(file->file_name, 1); - forward(file->fp, file->file_name, style, off, &file->st); - if (Fflag && fileno(file->fp) != STDIN_FILENO) - n++; - } + for (i = 0, file = files; i < no_files; i++, file++) { + if (!file->fp) + continue; + active = 1; + if (vflag || (qflag == 0 && no_files > 1)) + printfn(file->file_name, 1); + forward(file->fp, file->file_name, style, off, &file->st); } if (!Fflag && !active) return; @@ -334,9 +328,14 @@ follow(file_info_t *files, enum STYLE style, off_t off) kq = kqueue(); if (kq < 0) err(1, "kqueue"); - ev = malloc(n * sizeof(struct kevent)); - if (! ev) - err(1, "Couldn't allocate memory for kevents."); + /* + * The number of kqueue events we track may vary over time and may + * even grow past its initial value in the -F case, but it will + * never exceed two per file, so just preallocate that. + */ + ev = malloc(no_files * 2 * sizeof(struct kevent)); + if (ev == NULL) + err(1, "Couldn't allocate memory for kevents."); set_events(files); for (;;) { @@ -410,9 +409,7 @@ follow(file_info_t *files, enum STYLE style, off_t off) */ do { n = kevent(kq, NULL, 0, ev, 1, Fflag ? &ts : NULL); - if (n < 0 && errno == EINTR) - continue; - if (n < 0) + if (n < 0 && errno != EINTR) err(1, "kevent"); } while (n < 0); if (n == 0) { diff --git a/usr.bin/tail/tests/tail_test.sh b/usr.bin/tail/tests/tail_test.sh index 8123a310fe67..9c941f8a2c2f 100755 --- a/usr.bin/tail/tests/tail_test.sh +++ b/usr.bin/tail/tests/tail_test.sh @@ -329,10 +329,28 @@ follow_stdin_body() atf_check kill $pid } +atf_test_case follow_create +follow_create_head() +{ + atf_set "descr" "Verify that -F works when a file is created" +} +follow_create_body() +{ + local pid + + rm -f infile + tail -F infile > outfile & + pid=$! + seq 1 5 >infile + sleep 2 + atf_check cmp infile outfile + atf_check kill $pid +} + atf_test_case follow_rename follow_rename_head() { - atf_set "descr" "Verify that -F works" + atf_set "descr" "Verify that -F works when a file is replaced" } follow_rename_body() { @@ -424,6 +442,7 @@ atf_init_test_cases() atf_add_test_case stdin atf_add_test_case follow atf_add_test_case follow_stdin + atf_add_test_case follow_create atf_add_test_case follow_rename atf_add_test_case silent_header atf_add_test_case verbose_header |
