1 /* vi: set sw=4 ts=4: */
2 /* tail -- output the last part of file(s)
3 Copyright (C) 89, 90, 91, 95, 1996 Free Software Foundation, Inc.
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2, or (at your option)
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 Original version by Paul Rubin <phr@ocf.berkeley.edu>.
20 Extensions by David MacKenzie <djm@gnu.ai.mit.edu>.
21 tail -f for multiple files by Ian Lance Taylor <ian@airs.com>.
23 Rewrote the option parser, removed locales support,
24 and generally busyboxed, Erik Andersen <andersen@lineo.com>
26 Removed superfluous options and associated code ("-c", "-n", "-q").
27 Removed "tail -f" support for multiple files.
28 Both changes by Friedrich Vedder <fwv@myrtle.lahn.de>.
30 Compleate Rewrite to correctly support "-NUM", "+NUM", and "-s" by
31 E.Allen Soard (esp@espsw.net).
34 #include <sys/types.h>
44 #define STDIN "standard input"
48 static int n_files = 0;
49 static char **files = NULL;
53 #ifdef BB_FEATURE_SIMPLE_TAIL
54 static const char unit_type=LINES;
55 static const char sleep_int=1;
57 static char unit_type=LINES;
58 static int sleep_int=1;
59 static char verbose = 0;
62 //static off_t units=-11;
65 int tail_stream(int file_id)
70 ssize_t startpoint=bs;
74 ssize_t filelocation=0;
80 if (!strcmp(files[file_id], STDIN))
83 fd = open(files[file_id], O_RDONLY);
85 fatalError("Unable to open file %s.\n", files[file_id]);
89 filesize=lseek(fd, -1, SEEK_END)+1;
106 bytes_read=read(fd,line,bs);
109 buffer=realloc(buffer,f_size+bytes_read);
110 memcpy(&buffer[f_size],line,bytes_read);
111 filelocation=f_size+=bytes_read;
119 filelocation = lseek(fd, 0, SEEK_CUR);
123 filelocation = lseek(fd, -bs, SEEK_CUR);
125 bytes_read = read(fd, buffer, bs);
135 for(;startpoint!=endpoint;startpoint+=direction) {
136 #ifndef BB_FEATURE_SIMPLE_TAIL
141 if(buffer[startpoint-1]=='\n')
144 filelocation=lseek(fd,0,SEEK_CUR);
145 if(count==abs(units))
148 if((count==abs(units)) | pipe)
151 filelocation = lseek(fd, -bytes_read, SEEK_CUR);
156 if(pipe && (direction<0))
158 bytes_read=bs-startpoint;
159 memcpy(&buffer[0],&buffer[startpoint],bytes_read);
163 if((filelocation>0 || pipe)){
164 write(1,buffer,bytes_read);
166 bytes_read = read(fd, buffer, bs);
167 filelocation+=bytes_read;
168 if (bytes_read <= 0) {
175 usleep(sleep_int * 1000);
182 void add_file(char *name)
185 files = realloc(files, n_files);
186 files[n_files - 1] = (char *) malloc(strlen(name) + 1);
187 strcpy(files[n_files - 1], name);
191 int tail_main(int argc, char **argv)
193 int show_headers = 1;
209 argn = realloc(argn, nargs);
210 argn[nargs - 1] = (char *) malloc(strlen(argv[c]) + 1);
211 strcpy(argn[nargs - 1], argv[c]);
217 c = getopt_long_only(nargs, argn,
218 "c:fhn:s:qv", NULL, &opt_index);
223 #ifndef BB_FEATURE_SIMPLE_TAIL
230 if(optarg[strlen(optarg)-1]>'9') {
231 switch (optarg[strlen(optarg)-1]) {
239 test *= (1024 * 1024);
242 fprintf(stderr,"Size must be b,k, or m.");
255 sleep_int = atoi(optarg);
272 if (optarg[0] == '+')
280 errorMsg("\nUnknown arg: %c.\n\n",c);
284 while (optind < nargs) {
285 if (!strcmp(argn[optind], "-"))
288 add_file(argn[optind]);
298 #ifndef BB_FEATURE_SIMPLE_TAIL
302 for (test = 0; test < n_files; test++) {
304 printf("==> %s <==\n", files[test]);
316 c-file-style: "linux"