hi,
this patch adds the tail -F option (if FEATURE_FANCY_TAIL is set).
This is handy for watching logfiles that get rotated.

cheers,

Eric


Signed-off-by: Eric Lammerts <[email protected]>
---
 coreutils/Config.in |    2 +-
 coreutils/tail.c    |   27 ++++++++++++++++++++++++---
 2 files changed, 25 insertions(+), 4 deletions(-)

diff --git a/coreutils/Config.in b/coreutils/Config.in
index 1bc047c..cacfb96 100644
--- a/coreutils/Config.in
+++ b/coreutils/Config.in
@@ -635,7 +635,7 @@ config TAIL
          from files.

 config FEATURE_FANCY_TAIL
-       bool "Enable extra tail options (-q, -s, and -v)"
+       bool "Enable extra tail options (-q, -s, -v, and -F)"
        default y
        depends on TAIL
        help
diff --git a/coreutils/tail.c b/coreutils/tail.c
index 3ce6be0..12ec6fc 100644
--- a/coreutils/tail.c
+++ b/coreutils/tail.c
@@ -111,7 +111,7 @@ int tail_main(int argc, char **argv)
 #endif

        IF_FEATURE_FANCY_TAIL(opt_complementary = "s+";) /* -s N */
-       opt = getopt32(argv, "fc:n:" IF_FEATURE_FANCY_TAIL("qs:v"),
+       opt = getopt32(argv, "fc:n:" IF_FEATURE_FANCY_TAIL("qs:vF"),
                        &str_c, &str_n IF_FEATURE_FANCY_TAIL(,&sleep_period));
 #define FOLLOW (opt & 0x1)
 #define COUNT_BYTES (opt & 0x2)
@@ -121,6 +121,10 @@ int tail_main(int argc, char **argv)
 #if ENABLE_FEATURE_FANCY_TAIL
        if (opt & 0x8) header_threshhold = INT_MAX; // -q
        if (opt & 0x20) header_threshhold = 0; // -v
+#define FOLLOW_RETRY (opt & 0x40)
+       if (FOLLOW_RETRY) opt |= 0x1;
+#else
+#define FOLLOW_RETRY 0
 #endif
        argc -= optind;
        argv += optind;
@@ -140,7 +144,7 @@ int tail_main(int argc, char **argv)
        nfiles = i = 0;
        do {
                int fd = open_or_warn_stdin(argv[i]);
-               if (fd < 0) {
+               if (fd < 0 && !FOLLOW_RETRY) {
                        G.status = EXIT_FAILURE;
                        continue;
                }
@@ -164,6 +168,8 @@ int tail_main(int argc, char **argv)
        fmt = header_fmt + 1;   /* Skip header leading newline on first output. 
*/
        i = 0;
        do {
+               if (FOLLOW_RETRY && fds[i] < 0) continue;
+
                if (nfiles > header_threshhold) {
                        tail_xprint_header(fmt, argv[i]);
                        fmt = header_fmt;
@@ -265,10 +271,25 @@ int tail_main(int argc, char **argv)
                sleep(sleep_period);
                i = 0;
                do {
+                       if (FOLLOW_RETRY) {
+                               struct stat sbuf, fsbuf;
+
+                               if (fds[i] < 0 || fstat(fds[i], &fsbuf) < 0 || 
stat(argv[i], &sbuf) < 0 || fsbuf.st_dev != sbuf.st_dev || fsbuf.st_ino != 
sbuf.st_ino) {
+                                       int fd;
+
+                                       close(fds[i]);
+                                       if ((fd = open(argv[i], O_RDONLY)) >= 
0) {
+                                               bb_error_msg("%s has %s; 
following end of new file", argv[i], (fds[i] < 0)? "appeared" : "been 
replaced");
+                                       } else if(fds[i] >= 0) {
+                                               bb_perror_msg("%s has become 
inaccessible", argv[i]);
+                                       }
+                                       fds[i] = fd;
+                               }
+                       }
                        if (nfiles > header_threshhold) {
                                fmt = header_fmt;
                        }
-                       while ((nread = tail_read(fds[i], buf, BUFSIZ)) > 0) {
+                       if (!FOLLOW_RETRY || fds[i] >= 0) while ((nread = 
tail_read(fds[i], buf, BUFSIZ)) > 0) {
                                if (fmt) {
                                        tail_xprint_header(fmt, argv[i]);
                                        fmt = NULL;
-- 
1.5.6.3

_______________________________________________
busybox mailing list
[email protected]
http://lists.busybox.net/mailman/listinfo/busybox

Reply via email to