Update to the tail rewrite by "Allen Soard" <esp-software@mail.hypermart.net>
authorEric Andersen <andersen@codepoet.org>
Wed, 2 Aug 2000 16:42:58 +0000 (16:42 -0000)
committerEric Andersen <andersen@codepoet.org>
Wed, 2 Aug 2000 16:42:58 +0000 (16:42 -0000)
 -Erik

applets/usage.c
busybox.def.h
coreutils/tail.c
tail.c
usage.c

index 3f367f9b1e090595909365d3ebdd6d7e7a8165e9..1e2eb64cc1acc4b568ca55a11d491fca61556ca7 100644 (file)
@@ -1017,7 +1017,6 @@ const char syslogd_usage[] =
 #endif
 
 #if defined BB_TAIL
-#if defined BB_FEATURE_SIMPLE_TAIL
 const char tail_usage[] =
        "tail [OPTION] [FILE]...\n"
 #ifndef BB_FEATURE_TRIVIAL_HELP
@@ -1025,32 +1024,25 @@ const char tail_usage[] =
        "With more than one FILE, precede each with a header giving the\n"
        "file name. With no FILE, or when FILE is -, read standard input.\n\n"
        "Options:\n"
-       "\t-n NUM\t\tPrint last NUM lines instead of first 10\n"
-
-       "\t-f\t\tOutput data as the file grows.  This version\n"
-       "\t\t\tof 'tail -f' supports only one file at a time.\n"
+#ifndef BB_FEATURE_SIMPLE_TAIL
+       "\t-c=N[kbm]\toutput the last N bytes\n"
 #endif
-       ;
-#else /* ! defined BB_FEATURE_SIMPLE_TAIL */
-const char tail_usage[] =
-       "tail [OPTION]... [FILE]...\n"
-#ifndef BB_FEATURE_TRIVIAL_HELP
-       "\nPrint last 10 lines of each FILE to standard output.\n"
-       "With more than one FILE, precede each with a header giving the file name.\n"
-       "With no FILE, or when FILE is -, read standard input.\n"
-       "\n"
-       "  -c=N[kbm]       output the last N bytes\n"
-       "  -f              output appended data as the file grows\n"
-       "  -n=N            output the last N lines, instead of last 10\n"
-       "  -q              never output headers giving file names\n"
-       "  -v              always output headers giving file names\n"
-       "\n"
+       "\t-n NUM\t\tPrint last NUM lines instead of first 10\n"
+       "\t\t\tAlso can be -NUM or +NUM.\n"
+       "\t-f\t\tOutput data as the file grows.\n"
+#ifndef BB_FEATURE_SIMPLE_TAIL
+       "\t-q\t\tnever output headers giving file names\n"
+       "\t-s SEC\t\tWait SEC seconds between reads with -f\n"
+       "\t-v\t\talways output headers giving file names\n\n"
        "If the first character of N (bytes or lines) is a `+', output begins with \n"
        "the Nth item from the start of each file, otherwise, print the last N items\n"
-       "in the file.  N bytes may be suffixed by k (x1024), b (x512), or m (1024^2).\n"
+       "in the file. N bytes may be suffixed by k (x1024), b (x512), or m (1024^2).\n"
+//#else
+//     "\nIf the first character of N (bytes or lines) is a `+', output begins with \n"
+//     "the Nth item from the start of each file.\n"
 #endif
-       ;
 #endif
+       ;
 #endif
 
 #if defined BB_TAR
@@ -1061,9 +1053,9 @@ const char tar_usage[] =
        "tar -[xtvO] "
 #endif
 #if defined BB_FEATURE_TAR_EXCLUDE
-       "[--exclude File] "
+       "[-X File(s)] "
 #endif
-       "[-f tarFile] [FILE] ...\n"
+       "[-f tarFile] [FILE(s)] ...\n"
 #ifndef BB_FEATURE_TRIVIAL_HELP
        "\nCreate, extract, or list files from a tar file.  Note that\n"
        "this version of tar treats hard links as separate files.\n\n"
@@ -1077,7 +1069,7 @@ const char tar_usage[] =
        "\tf\t\tname of tarfile or \"-\" for stdin\n"
        "\tO\t\textract to stdout\n"
 #if defined BB_FEATURE_TAR_EXCLUDE
-       "\t--exclude\tfile to exclude\n"
+       "\tX\t\tfile(s) to exclude\n"
 #endif
        "\nInformative output:\n"
        "\tv\t\tverbosely list files processed\n"
index 41ba0ce8575641dacefaed8672231d805bd18a64..5adc3e57f974e7e23c37dfc7ffd295c9b137b9a8 100644 (file)
 // enable syslogd -R remotehost
 #define BB_FEATURE_REMOTE_LOG
 //
-//Simple tail implementation (2.25k vs 3k for the full one).
+//Simple tail implementation (2.34k vs 3k for the full one).
 //Both provide 'tail -f' support (only one file at a time.)
 #define BB_FEATURE_SIMPLE_TAIL
 //
index 4a1aa8436254d5ccb8018fb410525d376e4e2381..156f6368b3943f6ee0df55c0ab7b1fbf00ecf6d0 100644 (file)
 
 static int n_files = 0;
 static char **files = NULL;
-
-static char follow=0;
+static char * buffer;
+static ssize_t bytes_read=0;
+static ssize_t bs;
+static ssize_t filelocation=0;
+static char pip;
 
 #ifdef BB_FEATURE_SIMPLE_TAIL
 static const char unit_type=LINES;
-static const char sleep_int=1;
 #else
 static char unit_type=LINES;
-static int sleep_int=1;
 static char verbose = 0;
 #endif
 
-//static off_t units=-11;
 static off_t units=0;
 
-int tail_stream(int file_id)
+int tail_stream(int fd)
 {
-       int fd;
-       ssize_t bytes_read=0;
-       ssize_t bs=BUFSIZ;
-       ssize_t startpoint=bs;
+       ssize_t startpoint;
        ssize_t endpoint=0;
        ssize_t count=0;
        ssize_t filesize=0;
-       ssize_t filelocation=0;
        char direction=1;
-       char * buffer;
-       char pipe;
-
 
-       if (!strcmp(files[file_id], STDIN))
-               fd = 0;
-       else
-               fd = open(files[file_id], O_RDONLY);
-       if (fd == -1)
-               fatalError("Unable to open file %s.\n", files[file_id]);
-
-       buffer=malloc(bs);
+       filelocation=0;
+       startpoint=bs=BUFSIZ;
 
        filesize=lseek(fd, -1, SEEK_END)+1;
-       pipe=(filesize<=0);
+       pip=(filesize<=0);
 
        if(units>=0)
                lseek(fd,0,SEEK_SET);
@@ -96,7 +83,7 @@ int tail_stream(int file_id)
                count=1;
        }
        while(units != 0) {
-               if (pipe) {
+               if (pip) {
                        char * line;
                        ssize_t f_size=0;
 
@@ -140,12 +127,12 @@ int tail_stream(int file_id)
 #endif
                                if(buffer[startpoint-1]=='\n')
                                        count++;
-                       if (!pipe)
+                       if (!pip)
                                filelocation=lseek(fd,0,SEEK_CUR);
-                       if(count==abs(units))
+                       if(count==units*direction)
                                break;
                }
-               if((count==abs(units)) | pipe)
+               if((count==units*direction) | pip)
                        break;
                if(direction<0){
                        filelocation = lseek(fd, -bytes_read, SEEK_CUR);
@@ -153,29 +140,11 @@ int tail_stream(int file_id)
                                break;
                }
        }
-       if(pipe && (direction<0))
+       if(pip && (direction<0))
                bs++;
        bytes_read=bs-startpoint;
        memcpy(&buffer[0],&buffer[startpoint],bytes_read);
 
-       bs=BUFSIZ;
-       while (1) {
-               if((filelocation>0 || pipe)){
-                       write(1,buffer,bytes_read);
-               }
-               bytes_read = read(fd, buffer, bs);
-               filelocation+=bytes_read;
-               if (bytes_read <= 0) {
-                       if (!follow) {
-                               close(fd);
-                               break;
-                       }
-                       sleep(sleep_int);
-               }
-               usleep(sleep_int * 1000);
-       }
-       if (buffer)
-               free(buffer);
        return 0;
 }
 
@@ -192,33 +161,31 @@ int tail_main(int argc, char **argv)
 {
        int show_headers = 1;
        int test;
-       int c;
-       int nargs=0;
-       char **argn=NULL;
+       int opt;
+       int optc=0;
+       char **optv=NULL;
+       char follow=0;
+       int sleep_int=1;
+       int *fd;
 
        opterr = 0;
        
-       for(c=0;c<argc;c++){
-               test=atoi(argv[c]);
+       for(opt=0;opt<argc;opt++){
+               test=atoi(argv[opt]);
                if(test){
                        units=test;
                        if(units<0)
                                units=units-1;
                }else{
-                       nargs++;
-                       argn = realloc(argn, nargs);
-                       argn[nargs - 1] = (char *) malloc(strlen(argv[c]) + 1);
-                       strcpy(argn[nargs - 1], argv[c]);
+                       optc++;
+                       optv = realloc(optv, optc);
+                       optv[optc - 1] = (char *) malloc(strlen(argv[opt]) + 1);
+                       strcpy(optv[optc - 1], argv[opt]);
                }
        }
-       while (1) {
-               int opt_index = 0;
+       while ((opt=getopt(optc,optv,"c:fhn:s:q:v")) >0) {
 
-               c = getopt_long_only(nargs, argn,
-                       "c:fhn:s:qv", NULL, &opt_index);
-               if (c == -1)
-                       break;
-               switch (c) {
+               switch (opt) {
 
 #ifndef BB_FEATURE_SIMPLE_TAIL
 
@@ -277,37 +244,89 @@ int tail_main(int argc, char **argv)
                                usage(tail_usage);
                        break;
                default:
-                       errorMsg("\nUnknown arg: %c.\n\n",c);
+                       errorMsg("\nUnknown arg: %c.\n\n",optopt);
                        usage(tail_usage);
                }
        }
-       while (optind < nargs) {
-               if (!strcmp(argn[optind], "-"))
-                       add_file(STDIN);
-               else
-                       add_file(argn[optind]);
-               optind++;
+       while (optind <= optc) {
+               if(optind==optc) {
+                       if (n_files==0)
+                               add_file(STDIN);
+                       else
+                               break;
+               }else {
+                       if (!strcmp(optv[optind], "-"))
+                               add_file(STDIN);
+                       else
+                               add_file(optv[optind]);
+                       optind++;
+               }
        }
        if(units==0)
                units=-11;
        if(units>0)
                units--;
-       if (n_files == 0)
-               add_file(STDIN);
+       fd=malloc(sizeof(int)*n_files);
        if (n_files == 1)
 #ifndef BB_FEATURE_SIMPLE_TAIL
                if (!verbose)
 #endif
                        show_headers = 0;
+       buffer=malloc(BUFSIZ);
        for (test = 0; test < n_files; test++) {
                if (show_headers)
                        printf("==> %s <==\n", files[test]);
-               tail_stream(test);
+               if (!strcmp(files[test], STDIN))
+                       fd[test] = 0;
+               else
+                       fd[test] = open(files[test], O_RDONLY);
+               if (fd[test] == -1)
+                       fatalError("Unable to open file %s.\n", files[test]);
+               tail_stream(fd[test]);
+
+               bs=BUFSIZ;
+               while (1) {
+                       if((filelocation>0 || pip)){
+                               write(1,buffer,bytes_read);
+                       }
+                       bytes_read = read(fd[test], buffer, bs);
+                       filelocation+=bytes_read;
+                       if (bytes_read <= 0) {
+                               break;
+                       }
+                       usleep(sleep_int * 1000);
+               }
+               if(n_files>1)
+                       printf("\n");
        }
+       while(1){
+               for (test = 0; test < n_files; test++) {
+                       if(!follow){
+                               close(fd[test]);
+                               continue;
+                       } else {
+                               sleep(sleep_int);
+                               bytes_read = read(fd[test], buffer, bs);
+                               if(bytes_read>0) {
+                                       if (show_headers)
+                                               printf("==> %s <==\n", files[test]);
+                                       write(1,buffer,bytes_read);
+                                       if(n_files>1)
+                                               printf("\n");
+                               }
+                       }
+               }
+               if(!follow)
+                       break;
+       }
+       if (fd)
+               free(fd);
+       if (buffer)
+               free(buffer);
        if(files)
                free(files);
-       if(argn)
-               free(argn);
+       if(optv)
+               free(optv);
        return 0;
 }
 
diff --git a/tail.c b/tail.c
index 4a1aa8436254d5ccb8018fb410525d376e4e2381..156f6368b3943f6ee0df55c0ab7b1fbf00ecf6d0 100644 (file)
--- a/tail.c
+++ b/tail.c
 
 static int n_files = 0;
 static char **files = NULL;
-
-static char follow=0;
+static char * buffer;
+static ssize_t bytes_read=0;
+static ssize_t bs;
+static ssize_t filelocation=0;
+static char pip;
 
 #ifdef BB_FEATURE_SIMPLE_TAIL
 static const char unit_type=LINES;
-static const char sleep_int=1;
 #else
 static char unit_type=LINES;
-static int sleep_int=1;
 static char verbose = 0;
 #endif
 
-//static off_t units=-11;
 static off_t units=0;
 
-int tail_stream(int file_id)
+int tail_stream(int fd)
 {
-       int fd;
-       ssize_t bytes_read=0;
-       ssize_t bs=BUFSIZ;
-       ssize_t startpoint=bs;
+       ssize_t startpoint;
        ssize_t endpoint=0;
        ssize_t count=0;
        ssize_t filesize=0;
-       ssize_t filelocation=0;
        char direction=1;
-       char * buffer;
-       char pipe;
-
 
-       if (!strcmp(files[file_id], STDIN))
-               fd = 0;
-       else
-               fd = open(files[file_id], O_RDONLY);
-       if (fd == -1)
-               fatalError("Unable to open file %s.\n", files[file_id]);
-
-       buffer=malloc(bs);
+       filelocation=0;
+       startpoint=bs=BUFSIZ;
 
        filesize=lseek(fd, -1, SEEK_END)+1;
-       pipe=(filesize<=0);
+       pip=(filesize<=0);
 
        if(units>=0)
                lseek(fd,0,SEEK_SET);
@@ -96,7 +83,7 @@ int tail_stream(int file_id)
                count=1;
        }
        while(units != 0) {
-               if (pipe) {
+               if (pip) {
                        char * line;
                        ssize_t f_size=0;
 
@@ -140,12 +127,12 @@ int tail_stream(int file_id)
 #endif
                                if(buffer[startpoint-1]=='\n')
                                        count++;
-                       if (!pipe)
+                       if (!pip)
                                filelocation=lseek(fd,0,SEEK_CUR);
-                       if(count==abs(units))
+                       if(count==units*direction)
                                break;
                }
-               if((count==abs(units)) | pipe)
+               if((count==units*direction) | pip)
                        break;
                if(direction<0){
                        filelocation = lseek(fd, -bytes_read, SEEK_CUR);
@@ -153,29 +140,11 @@ int tail_stream(int file_id)
                                break;
                }
        }
-       if(pipe && (direction<0))
+       if(pip && (direction<0))
                bs++;
        bytes_read=bs-startpoint;
        memcpy(&buffer[0],&buffer[startpoint],bytes_read);
 
-       bs=BUFSIZ;
-       while (1) {
-               if((filelocation>0 || pipe)){
-                       write(1,buffer,bytes_read);
-               }
-               bytes_read = read(fd, buffer, bs);
-               filelocation+=bytes_read;
-               if (bytes_read <= 0) {
-                       if (!follow) {
-                               close(fd);
-                               break;
-                       }
-                       sleep(sleep_int);
-               }
-               usleep(sleep_int * 1000);
-       }
-       if (buffer)
-               free(buffer);
        return 0;
 }
 
@@ -192,33 +161,31 @@ int tail_main(int argc, char **argv)
 {
        int show_headers = 1;
        int test;
-       int c;
-       int nargs=0;
-       char **argn=NULL;
+       int opt;
+       int optc=0;
+       char **optv=NULL;
+       char follow=0;
+       int sleep_int=1;
+       int *fd;
 
        opterr = 0;
        
-       for(c=0;c<argc;c++){
-               test=atoi(argv[c]);
+       for(opt=0;opt<argc;opt++){
+               test=atoi(argv[opt]);
                if(test){
                        units=test;
                        if(units<0)
                                units=units-1;
                }else{
-                       nargs++;
-                       argn = realloc(argn, nargs);
-                       argn[nargs - 1] = (char *) malloc(strlen(argv[c]) + 1);
-                       strcpy(argn[nargs - 1], argv[c]);
+                       optc++;
+                       optv = realloc(optv, optc);
+                       optv[optc - 1] = (char *) malloc(strlen(argv[opt]) + 1);
+                       strcpy(optv[optc - 1], argv[opt]);
                }
        }
-       while (1) {
-               int opt_index = 0;
+       while ((opt=getopt(optc,optv,"c:fhn:s:q:v")) >0) {
 
-               c = getopt_long_only(nargs, argn,
-                       "c:fhn:s:qv", NULL, &opt_index);
-               if (c == -1)
-                       break;
-               switch (c) {
+               switch (opt) {
 
 #ifndef BB_FEATURE_SIMPLE_TAIL
 
@@ -277,37 +244,89 @@ int tail_main(int argc, char **argv)
                                usage(tail_usage);
                        break;
                default:
-                       errorMsg("\nUnknown arg: %c.\n\n",c);
+                       errorMsg("\nUnknown arg: %c.\n\n",optopt);
                        usage(tail_usage);
                }
        }
-       while (optind < nargs) {
-               if (!strcmp(argn[optind], "-"))
-                       add_file(STDIN);
-               else
-                       add_file(argn[optind]);
-               optind++;
+       while (optind <= optc) {
+               if(optind==optc) {
+                       if (n_files==0)
+                               add_file(STDIN);
+                       else
+                               break;
+               }else {
+                       if (!strcmp(optv[optind], "-"))
+                               add_file(STDIN);
+                       else
+                               add_file(optv[optind]);
+                       optind++;
+               }
        }
        if(units==0)
                units=-11;
        if(units>0)
                units--;
-       if (n_files == 0)
-               add_file(STDIN);
+       fd=malloc(sizeof(int)*n_files);
        if (n_files == 1)
 #ifndef BB_FEATURE_SIMPLE_TAIL
                if (!verbose)
 #endif
                        show_headers = 0;
+       buffer=malloc(BUFSIZ);
        for (test = 0; test < n_files; test++) {
                if (show_headers)
                        printf("==> %s <==\n", files[test]);
-               tail_stream(test);
+               if (!strcmp(files[test], STDIN))
+                       fd[test] = 0;
+               else
+                       fd[test] = open(files[test], O_RDONLY);
+               if (fd[test] == -1)
+                       fatalError("Unable to open file %s.\n", files[test]);
+               tail_stream(fd[test]);
+
+               bs=BUFSIZ;
+               while (1) {
+                       if((filelocation>0 || pip)){
+                               write(1,buffer,bytes_read);
+                       }
+                       bytes_read = read(fd[test], buffer, bs);
+                       filelocation+=bytes_read;
+                       if (bytes_read <= 0) {
+                               break;
+                       }
+                       usleep(sleep_int * 1000);
+               }
+               if(n_files>1)
+                       printf("\n");
        }
+       while(1){
+               for (test = 0; test < n_files; test++) {
+                       if(!follow){
+                               close(fd[test]);
+                               continue;
+                       } else {
+                               sleep(sleep_int);
+                               bytes_read = read(fd[test], buffer, bs);
+                               if(bytes_read>0) {
+                                       if (show_headers)
+                                               printf("==> %s <==\n", files[test]);
+                                       write(1,buffer,bytes_read);
+                                       if(n_files>1)
+                                               printf("\n");
+                               }
+                       }
+               }
+               if(!follow)
+                       break;
+       }
+       if (fd)
+               free(fd);
+       if (buffer)
+               free(buffer);
        if(files)
                free(files);
-       if(argn)
-               free(argn);
+       if(optv)
+               free(optv);
        return 0;
 }
 
diff --git a/usage.c b/usage.c
index 3f367f9b1e090595909365d3ebdd6d7e7a8165e9..1e2eb64cc1acc4b568ca55a11d491fca61556ca7 100644 (file)
--- a/usage.c
+++ b/usage.c
@@ -1017,7 +1017,6 @@ const char syslogd_usage[] =
 #endif
 
 #if defined BB_TAIL
-#if defined BB_FEATURE_SIMPLE_TAIL
 const char tail_usage[] =
        "tail [OPTION] [FILE]...\n"
 #ifndef BB_FEATURE_TRIVIAL_HELP
@@ -1025,32 +1024,25 @@ const char tail_usage[] =
        "With more than one FILE, precede each with a header giving the\n"
        "file name. With no FILE, or when FILE is -, read standard input.\n\n"
        "Options:\n"
-       "\t-n NUM\t\tPrint last NUM lines instead of first 10\n"
-
-       "\t-f\t\tOutput data as the file grows.  This version\n"
-       "\t\t\tof 'tail -f' supports only one file at a time.\n"
+#ifndef BB_FEATURE_SIMPLE_TAIL
+       "\t-c=N[kbm]\toutput the last N bytes\n"
 #endif
-       ;
-#else /* ! defined BB_FEATURE_SIMPLE_TAIL */
-const char tail_usage[] =
-       "tail [OPTION]... [FILE]...\n"
-#ifndef BB_FEATURE_TRIVIAL_HELP
-       "\nPrint last 10 lines of each FILE to standard output.\n"
-       "With more than one FILE, precede each with a header giving the file name.\n"
-       "With no FILE, or when FILE is -, read standard input.\n"
-       "\n"
-       "  -c=N[kbm]       output the last N bytes\n"
-       "  -f              output appended data as the file grows\n"
-       "  -n=N            output the last N lines, instead of last 10\n"
-       "  -q              never output headers giving file names\n"
-       "  -v              always output headers giving file names\n"
-       "\n"
+       "\t-n NUM\t\tPrint last NUM lines instead of first 10\n"
+       "\t\t\tAlso can be -NUM or +NUM.\n"
+       "\t-f\t\tOutput data as the file grows.\n"
+#ifndef BB_FEATURE_SIMPLE_TAIL
+       "\t-q\t\tnever output headers giving file names\n"
+       "\t-s SEC\t\tWait SEC seconds between reads with -f\n"
+       "\t-v\t\talways output headers giving file names\n\n"
        "If the first character of N (bytes or lines) is a `+', output begins with \n"
        "the Nth item from the start of each file, otherwise, print the last N items\n"
-       "in the file.  N bytes may be suffixed by k (x1024), b (x512), or m (1024^2).\n"
+       "in the file. N bytes may be suffixed by k (x1024), b (x512), or m (1024^2).\n"
+//#else
+//     "\nIf the first character of N (bytes or lines) is a `+', output begins with \n"
+//     "the Nth item from the start of each file.\n"
 #endif
-       ;
 #endif
+       ;
 #endif
 
 #if defined BB_TAR
@@ -1061,9 +1053,9 @@ const char tar_usage[] =
        "tar -[xtvO] "
 #endif
 #if defined BB_FEATURE_TAR_EXCLUDE
-       "[--exclude File] "
+       "[-X File(s)] "
 #endif
-       "[-f tarFile] [FILE] ...\n"
+       "[-f tarFile] [FILE(s)] ...\n"
 #ifndef BB_FEATURE_TRIVIAL_HELP
        "\nCreate, extract, or list files from a tar file.  Note that\n"
        "this version of tar treats hard links as separate files.\n\n"
@@ -1077,7 +1069,7 @@ const char tar_usage[] =
        "\tf\t\tname of tarfile or \"-\" for stdin\n"
        "\tO\t\textract to stdout\n"
 #if defined BB_FEATURE_TAR_EXCLUDE
-       "\t--exclude\tfile to exclude\n"
+       "\tX\t\tfile(s) to exclude\n"
 #endif
        "\nInformative output:\n"
        "\tv\t\tverbosely list files processed\n"