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>
43 #define STDIN "standard input"
47 static int n_files = 0;
48 static char **files = NULL;
50 static ssize_t bytes_read=0;
52 static ssize_t filelocation=0;
55 #ifdef BB_FEATURE_SIMPLE_TAIL
56 static const char unit_type=LINES;
58 static char unit_type=LINES;
59 static char verbose = 0;
64 static struct suffix_mult tail_suffixes[] = {
71 static int tail_stream(int fd)
82 filesize=lseek(fd, -1, SEEK_END)+1;
99 bytes_read=read(fd,line,bs);
102 buffer=xrealloc(buffer,f_size+bytes_read);
103 memcpy(&buffer[f_size],line,bytes_read);
104 filelocation=f_size+=bytes_read;
112 filelocation = lseek(fd, 0, SEEK_CUR);
116 filelocation = lseek(fd, -bs, SEEK_CUR);
118 bytes_read = read(fd, buffer, bs);
128 for(;startpoint!=endpoint;startpoint+=direction) {
129 #ifndef BB_FEATURE_SIMPLE_TAIL
134 if(buffer[startpoint-1]=='\n')
137 filelocation=lseek(fd,0,SEEK_CUR);
138 if(count==units*direction)
141 if((count==units*direction) | pip)
144 filelocation = lseek(fd, -bytes_read, SEEK_CUR);
149 if(pip && (direction<0))
151 bytes_read=bs-startpoint;
152 memcpy(&buffer[0],&buffer[startpoint],bytes_read);
157 void add_file(char *name)
160 files = xrealloc(files, n_files);
161 files[n_files - 1] = (char *) xmalloc(strlen(name) + 1);
162 strcpy(files[n_files - 1], name);
165 int tail_main(int argc, char **argv)
167 int show_headers = 1;
176 while ((opt=getopt(argc,argv,"c:fhn:s:q:v")) >0) {
179 #ifndef BB_FEATURE_SIMPLE_TAIL
184 sleep_int = atoi(optarg);
196 test = parse_number(optarg, tail_suffixes);
198 if (optarg[0] == '+')
212 while (optind <= argc) {
219 if (!strcmp(argv[optind], "-")) {
222 add_file(argv[optind]);
231 fd=xmalloc(sizeof(int)*n_files);
233 #ifndef BB_FEATURE_SIMPLE_TAIL
237 buffer=xmalloc(BUFSIZ);
238 for (test = 0; test < n_files; test++) {
240 printf("==> %s <==\n", files[test]);
241 if (!strcmp(files[test], STDIN))
244 fd[test] = open(files[test], O_RDONLY);
246 error_msg_and_die("Unable to open file %s.\n", files[test]);
247 tail_stream(fd[test]);
251 if((filelocation>0 || pip)){
252 write(1,buffer,bytes_read);
254 bytes_read = read(fd[test], buffer, bs);
255 filelocation+=bytes_read;
256 if (bytes_read <= 0) {
259 usleep(sleep_int * 1000);
265 for (test = 0; test < n_files; test++) {
271 bytes_read = read(fd[test], buffer, bs);
274 printf("==> %s <==\n", files[test]);
275 write(1,buffer,bytes_read);
295 c-file-style: "linux"