Fixed spelling error
[oweals/busybox.git] / tail.c
1 /* tail -- output the last part of file(s)
2    Copyright (C) 89, 90, 91, 95, 1996 Free Software Foundation, Inc.
3
4    This program is free software; you can redistribute it and/or modify
5    it under the terms of the GNU General Public License as published by
6    the Free Software Foundation; either version 2, or (at your option)
7    any later version.
8
9    This program is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12    GNU General Public License for more details.
13
14    You should have received a copy of the GNU General Public License
15    along with this program; if not, write to the Free Software
16    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
17
18 /* Can display any amount of data, unlike the Unix version, which uses
19    a fixed size buffer and therefore can only deliver a limited number
20    of lines.
21
22    Options:
23    -b                   Tail by N 512-byte blocks.
24    -c, --bytes=N[bkm]   Tail by N bytes
25                         [or 512-byte blocks, kilobytes, or megabytes].
26    -f, --follow         Loop forever trying to read more characters at the
27                         end of the file, on the assumption that the file
28                         is growing.  Ignored if reading from a pipe.
29    -n, --lines=N        Tail by N lines.
30    -q, --quiet, --silent        Never print filename headers.
31    -v, --verbose                Always print filename headers.
32
33    If a number (N) starts with a `+', begin printing with the Nth item
34    from the start of each file, instead of from the end.
35
36    Reads from standard input if no files are given or when a filename of
37    ``-'' is encountered.
38    By default, filename headers are printed only more than one file
39    is given.
40    By default, prints the last 10 lines (tail -n 10).
41
42    Original version by Paul Rubin <phr@ocf.berkeley.edu>.
43    Extensions by David MacKenzie <djm@gnu.ai.mit.edu>.
44    tail -f for multiple files by Ian Lance Taylor <ian@airs.com>.  */
45
46 #include "internal.h"
47
48 #include <stdio.h>
49 #include <assert.h>
50 #include <errno.h>
51 #include <sys/types.h>
52
53
54 /* Disable assertions.  Some systems have broken assert macros.  */
55 #define NDEBUG 1
56
57
58 static void error(int i, int errnum, char* fmt, const char *msg)
59 {
60     fprintf(stderr, fmt, msg);
61     perror( errnum);
62     exit(i);
63 }
64
65
66 #define XWRITE(fd, buffer, n_bytes)                                     \
67   do                                                                    \
68     {                                                                   \
69       assert ((fd) == 1);                                               \
70       assert ((n_bytes) >= 0);                                          \
71       if (n_bytes > 0 && fwrite ((buffer), 1, (n_bytes), stdout) == 0)  \
72         error (EXIT_FAILURE, errno, "write error", NULL);                       \
73     }                                                                   \
74   while (0)
75
76 /* Number of items to tail.  */
77 #define DEFAULT_N_LINES 10
78
79 /* Size of atomic reads.  */
80 #ifndef BUFSIZ
81 #define BUFSIZ (512 * 8)
82 #endif
83
84 /* If nonzero, interpret the numeric argument as the number of lines.
85    Otherwise, interpret it as the number of bytes.  */
86 static int count_lines;
87
88 /* If nonzero, read from the end of one file until killed.  */
89 static int forever;
90
91 /* If nonzero, read from the end of multiple files until killed.  */
92 static int forever_multiple;
93
94 /* Array of file descriptors if forever_multiple is 1.  */
95 static int *file_descs;
96
97 /* Array of file sizes if forever_multiple is 1.  */
98 static off_t *file_sizes;
99
100 /* If nonzero, count from start of file instead of end.  */
101 static int from_start;
102
103 /* If nonzero, print filename headers.  */
104 static int print_headers;
105
106 /* When to print the filename banners.  */
107 enum header_mode
108 {
109   multiple_files, always, never
110 };
111
112 char *xmalloc ();
113 int safe_read ();
114
115 /* The name this program was run with.  */
116 char *program_name;
117
118 /* Nonzero if we have ever read standard input.  */
119 static int have_read_stdin;
120
121 /* If nonzero, display usage information and exit.  */
122 static int show_help;
123
124 /* If nonzero, print the version on standard output then exit.  */
125 static int show_version;
126
127 static const char tail_usage[] = 
128 "tail [OPTION]... [FILE]...\n\
129 Print last 10 lines of each FILE to standard output.\n\
130 With more than one FILE, precede each with a header giving the file name.\n\
131 With no FILE, or when FILE is -, read standard input.\n\
132 \n\
133   -c, --bytes=N            output the last N bytes\n\
134   -f, --follow             output appended data as the file grows\n\
135   -n, --lines=N            output the last N lines, instead of last 10\n\
136   -q, --quiet, --silent    never output headers giving file names\n\
137   -v, --verbose            always output headers giving file names\n\
138       --help               display this help and exit\n\
139       --version            output version information and exit\n\
140 \n\
141 If the first character of N (the number of bytes or lines) is a `+',\n\
142 print beginning with the Nth item from the start of each file, otherwise,\n\
143 print the last N items in the file.  N may have a multiplier suffix:\n\
144 b for 512, k for 1024, m for 1048576 (1 Meg).  A first OPTION of -VALUE\n\
145 or +VALUE is treated like -n VALUE or -n +VALUE unless VALUE has one of\n\
146 the [bkm] suffix multipliers, in which case it is treated like -c VALUE\n\
147 or -c +VALUE.\n";
148
149 static void
150 write_header (const char *filename, const char *comment)
151 {
152   static int first_file = 1;
153
154   printf ("%s==> %s%s%s <==\n", (first_file ? "" : "\n"), filename,
155           (comment ? ": " : ""),
156           (comment ? comment : ""));
157   first_file = 0;
158 }
159
160 /* Print the last N_LINES lines from the end of file FD.
161    Go backward through the file, reading `BUFSIZ' bytes at a time (except
162    probably the first), until we hit the start of the file or have
163    read NUMBER newlines.
164    POS starts out as the length of the file (the offset of the last
165    byte of the file + 1).
166    Return 0 if successful, 1 if an error occurred.  */
167
168 static int
169 file_lines (const char *filename, int fd, long int n_lines, off_t pos)
170 {
171   char buffer[BUFSIZ];
172   int bytes_read;
173   int i;                        /* Index into `buffer' for scanning.  */
174
175   if (n_lines == 0)
176     return 0;
177
178   /* Set `bytes_read' to the size of the last, probably partial, buffer;
179      0 < `bytes_read' <= `BUFSIZ'.  */
180   bytes_read = pos % BUFSIZ;
181   if (bytes_read == 0)
182     bytes_read = BUFSIZ;
183   /* Make `pos' a multiple of `BUFSIZ' (0 if the file is short), so that all
184      reads will be on block boundaries, which might increase efficiency.  */
185   pos -= bytes_read;
186   lseek (fd, pos, SEEK_SET);
187   bytes_read = safe_read (fd, buffer, bytes_read);
188   if (bytes_read == -1)
189     {
190       error (0, errno, "%s", filename);
191       return 1;
192     }
193
194   /* Count the incomplete line on files that don't end with a newline.  */
195   if (bytes_read && buffer[bytes_read - 1] != '\n')
196     --n_lines;
197
198   do
199     {
200       /* Scan backward, counting the newlines in this bufferfull.  */
201       for (i = bytes_read - 1; i >= 0; i--)
202         {
203           /* Have we counted the requested number of newlines yet?  */
204           if (buffer[i] == '\n' && n_lines-- == 0)
205             {
206               /* If this newline wasn't the last character in the buffer,
207                  print the text after it.  */
208               if (i != bytes_read - 1)
209                 XWRITE (STDOUT_FILENO, &buffer[i + 1], bytes_read - (i + 1));
210               return 0;
211             }
212         }
213       /* Not enough newlines in that bufferfull.  */
214       if (pos == 0)
215         {
216           /* Not enough lines in the file; print the entire file.  */
217           lseek (fd, (off_t) 0, SEEK_SET);
218           return 0;
219         }
220       pos -= BUFSIZ;
221       lseek (fd, pos, SEEK_SET);
222     }
223   while ((bytes_read = safe_read (fd, buffer, BUFSIZ)) > 0);
224   if (bytes_read == -1)
225     {
226       error (0, errno, "%s", filename);
227       return 1;
228     }
229   return 0;
230 }
231
232 /* Print the last N_LINES lines from the end of the standard input,
233    open for reading as pipe FD.
234    Buffer the text as a linked list of LBUFFERs, adding them as needed.
235    Return 0 if successful, 1 if an error occured.  */
236
237 static int
238 pipe_lines (const char *filename, int fd, long int n_lines)
239 {
240   struct linebuffer
241   {
242     int nbytes, nlines;
243     char buffer[BUFSIZ];
244     struct linebuffer *next;
245   };
246   typedef struct linebuffer LBUFFER;
247   LBUFFER *first, *last, *tmp;
248   int i;                        /* Index into buffers.  */
249   int total_lines = 0;          /* Total number of newlines in all buffers.  */
250   int errors = 0;
251
252   first = last = (LBUFFER *) xmalloc (sizeof (LBUFFER));
253   first->nbytes = first->nlines = 0;
254   first->next = NULL;
255   tmp = (LBUFFER *) xmalloc (sizeof (LBUFFER));
256
257   /* Input is always read into a fresh buffer.  */
258   while ((tmp->nbytes = safe_read (fd, tmp->buffer, BUFSIZ)) > 0)
259     {
260       tmp->nlines = 0;
261       tmp->next = NULL;
262
263       /* Count the number of newlines just read.  */
264       for (i = 0; i < tmp->nbytes; i++)
265         if (tmp->buffer[i] == '\n')
266           ++tmp->nlines;
267       total_lines += tmp->nlines;
268
269       /* If there is enough room in the last buffer read, just append the new
270          one to it.  This is because when reading from a pipe, `nbytes' can
271          often be very small.  */
272       if (tmp->nbytes + last->nbytes < BUFSIZ)
273         {
274           memcpy (&last->buffer[last->nbytes], tmp->buffer, tmp->nbytes);
275           last->nbytes += tmp->nbytes;
276           last->nlines += tmp->nlines;
277         }
278       else
279         {
280           /* If there's not enough room, link the new buffer onto the end of
281              the list, then either free up the oldest buffer for the next
282              read if that would leave enough lines, or else malloc a new one.
283              Some compaction mechanism is possible but probably not
284              worthwhile.  */
285           last = last->next = tmp;
286           if (total_lines - first->nlines > n_lines)
287             {
288               tmp = first;
289               total_lines -= first->nlines;
290               first = first->next;
291             }
292           else
293             tmp = (LBUFFER *) xmalloc (sizeof (LBUFFER));
294         }
295     }
296   if (tmp->nbytes == -1)
297     {
298       error (0, errno, "%s", filename);
299       errors = 1;
300       free ((char *) tmp);
301       goto free_lbuffers;
302     }
303
304   free ((char *) tmp);
305
306   /* This prevents a core dump when the pipe contains no newlines.  */
307   if (n_lines == 0)
308     goto free_lbuffers;
309
310   /* Count the incomplete line on files that don't end with a newline.  */
311   if (last->buffer[last->nbytes - 1] != '\n')
312     {
313       ++last->nlines;
314       ++total_lines;
315     }
316
317   /* Run through the list, printing lines.  First, skip over unneeded
318      buffers.  */
319   for (tmp = first; total_lines - tmp->nlines > n_lines; tmp = tmp->next)
320     total_lines -= tmp->nlines;
321
322   /* Find the correct beginning, then print the rest of the file.  */
323   if (total_lines > n_lines)
324     {
325       char *cp;
326
327       /* Skip `total_lines' - `n_lines' newlines.  We made sure that
328          `total_lines' - `n_lines' <= `tmp->nlines'.  */
329       cp = tmp->buffer;
330       for (i = total_lines - n_lines; i; --i)
331         while (*cp++ != '\n')
332           /* Do nothing.  */ ;
333       i = cp - tmp->buffer;
334     }
335   else
336     i = 0;
337   XWRITE (STDOUT_FILENO, &tmp->buffer[i], tmp->nbytes - i);
338
339   for (tmp = tmp->next; tmp; tmp = tmp->next)
340     XWRITE (STDOUT_FILENO, tmp->buffer, tmp->nbytes);
341
342 free_lbuffers:
343   while (first)
344     {
345       tmp = first->next;
346       free ((char *) first);
347       first = tmp;
348     }
349   return errors;
350 }
351
352 /* Print the last N_BYTES characters from the end of pipe FD.
353    This is a stripped down version of pipe_lines.
354    Return 0 if successful, 1 if an error occurred.  */
355
356 static int
357 pipe_bytes (const char *filename, int fd, off_t n_bytes)
358 {
359   struct charbuffer
360   {
361     int nbytes;
362     char buffer[BUFSIZ];
363     struct charbuffer *next;
364   };
365   typedef struct charbuffer CBUFFER;
366   CBUFFER *first, *last, *tmp;
367   int i;                        /* Index into buffers.  */
368   int total_bytes = 0;          /* Total characters in all buffers.  */
369   int errors = 0;
370
371   first = last = (CBUFFER *) xmalloc (sizeof (CBUFFER));
372   first->nbytes = 0;
373   first->next = NULL;
374   tmp = (CBUFFER *) xmalloc (sizeof (CBUFFER));
375
376   /* Input is always read into a fresh buffer.  */
377   while ((tmp->nbytes = safe_read (fd, tmp->buffer, BUFSIZ)) > 0)
378     {
379       tmp->next = NULL;
380
381       total_bytes += tmp->nbytes;
382       /* If there is enough room in the last buffer read, just append the new
383          one to it.  This is because when reading from a pipe, `nbytes' can
384          often be very small.  */
385       if (tmp->nbytes + last->nbytes < BUFSIZ)
386         {
387           memcpy (&last->buffer[last->nbytes], tmp->buffer, tmp->nbytes);
388           last->nbytes += tmp->nbytes;
389         }
390       else
391         {
392           /* If there's not enough room, link the new buffer onto the end of
393              the list, then either free up the oldest buffer for the next
394              read if that would leave enough characters, or else malloc a new
395              one.  Some compaction mechanism is possible but probably not
396              worthwhile.  */
397           last = last->next = tmp;
398           if (total_bytes - first->nbytes > n_bytes)
399             {
400               tmp = first;
401               total_bytes -= first->nbytes;
402               first = first->next;
403             }
404           else
405             {
406               tmp = (CBUFFER *) xmalloc (sizeof (CBUFFER));
407             }
408         }
409     }
410   if (tmp->nbytes == -1)
411     {
412       error (0, errno, "%s", filename);
413       errors = 1;
414       free ((char *) tmp);
415       goto free_cbuffers;
416     }
417
418   free ((char *) tmp);
419
420   /* Run through the list, printing characters.  First, skip over unneeded
421      buffers.  */
422   for (tmp = first; total_bytes - tmp->nbytes > n_bytes; tmp = tmp->next)
423     total_bytes -= tmp->nbytes;
424
425   /* Find the correct beginning, then print the rest of the file.
426      We made sure that `total_bytes' - `n_bytes' <= `tmp->nbytes'.  */
427   if (total_bytes > n_bytes)
428     i = total_bytes - n_bytes;
429   else
430     i = 0;
431   XWRITE (STDOUT_FILENO, &tmp->buffer[i], tmp->nbytes - i);
432
433   for (tmp = tmp->next; tmp; tmp = tmp->next)
434     XWRITE (STDOUT_FILENO, tmp->buffer, tmp->nbytes);
435
436 free_cbuffers:
437   while (first)
438     {
439       tmp = first->next;
440       free ((char *) first);
441       first = tmp;
442     }
443   return errors;
444 }
445
446 /* Skip N_BYTES characters from the start of pipe FD, and print
447    any extra characters that were read beyond that.
448    Return 1 on error, 0 if ok.  */
449
450 static int
451 start_bytes (const char *filename, int fd, off_t n_bytes)
452 {
453   char buffer[BUFSIZ];
454   int bytes_read = 0;
455
456   while (n_bytes > 0 && (bytes_read = safe_read (fd, buffer, BUFSIZ)) > 0)
457     n_bytes -= bytes_read;
458   if (bytes_read == -1)
459     {
460       error (0, errno, "%s", filename);
461       return 1;
462     }
463   else if (n_bytes < 0)
464     XWRITE (STDOUT_FILENO, &buffer[bytes_read + n_bytes], -n_bytes);
465   return 0;
466 }
467
468 /* Skip N_LINES lines at the start of file or pipe FD, and print
469    any extra characters that were read beyond that.
470    Return 1 on error, 0 if ok.  */
471
472 static int
473 start_lines (const char *filename, int fd, long int n_lines)
474 {
475   char buffer[BUFSIZ];
476   int bytes_read = 0;
477   int bytes_to_skip = 0;
478
479   while (n_lines && (bytes_read = safe_read (fd, buffer, BUFSIZ)) > 0)
480     {
481       bytes_to_skip = 0;
482       while (bytes_to_skip < bytes_read)
483         if (buffer[bytes_to_skip++] == '\n' && --n_lines == 0)
484           break;
485     }
486   if (bytes_read == -1)
487     {
488       error (0, errno, "%s", filename);
489       return 1;
490     }
491   else if (bytes_to_skip < bytes_read)
492     {
493       XWRITE (STDOUT_FILENO, &buffer[bytes_to_skip],
494               bytes_read - bytes_to_skip);
495     }
496   return 0;
497 }
498
499 /* Display file FILENAME from the current position in FD to the end.
500    If `forever' is nonzero, keep reading from the end of the file
501    until killed.  Return the number of bytes read from the file.  */
502
503 static long
504 dump_remainder (const char *filename, int fd)
505 {
506   char buffer[BUFSIZ];
507   int bytes_read;
508   long total;
509
510   total = 0;
511 output:
512   while ((bytes_read = safe_read (fd, buffer, BUFSIZ)) > 0)
513     {
514       XWRITE (STDOUT_FILENO, buffer, bytes_read);
515       total += bytes_read;
516     }
517   if (bytes_read == -1)
518     error (EXIT_FAILURE, errno, "%s", filename);
519   if (forever)
520     {
521       fflush (stdout);
522       sleep (1);
523       goto output;
524     }
525   else
526     {
527       if (forever_multiple)
528         fflush (stdout);
529     }
530
531   return total;
532 }
533
534 /* Tail NFILES (>1) files forever until killed.  The file names are in
535    NAMES.  The open file descriptors are in `file_descs', and the size
536    at which we stopped tailing them is in `file_sizes'.  We loop over
537    each of them, doing an fstat to see if they have changed size.  If
538    none of them have changed size in one iteration, we sleep for a
539    second and try again.  We do this until the user interrupts us.  */
540
541 static void
542 tail_forever (char **names, int nfiles)
543 {
544   int last;
545
546   last = -1;
547
548   while (1)
549     {
550       int i;
551       int changed;
552
553       changed = 0;
554       for (i = 0; i < nfiles; i++)
555         {
556           struct stat stats;
557
558           if (file_descs[i] < 0)
559             continue;
560           if (fstat (file_descs[i], &stats) < 0)
561             {
562               error (0, errno, "%s", names[i]);
563               file_descs[i] = -1;
564               continue;
565             }
566           if (stats.st_size == file_sizes[i])
567             continue;
568
569           /* This file has changed size.  Print out what we can, and
570              then keep looping.  */
571
572           changed = 1;
573
574           if (stats.st_size < file_sizes[i])
575             {
576               write_header (names[i], "file truncated");
577               last = i;
578               lseek (file_descs[i], stats.st_size, SEEK_SET);
579               file_sizes[i] = stats.st_size;
580               continue;
581             }
582
583           if (i != last)
584             {
585               if (print_headers)
586                 write_header (names[i], NULL);
587               last = i;
588             }
589           file_sizes[i] += dump_remainder (names[i], file_descs[i]);
590         }
591
592       /* If none of the files changed size, sleep.  */
593       if (! changed)
594         sleep (1);
595     }
596 }
597
598 /* Output the last N_BYTES bytes of file FILENAME open for reading in FD.
599    Return 0 if successful, 1 if an error occurred.  */
600
601 static int
602 tail_bytes (const char *filename, int fd, off_t n_bytes)
603 {
604   struct stat stats;
605
606   /* FIXME: resolve this like in dd.c.  */
607   /* Use fstat instead of checking for errno == ESPIPE because
608      lseek doesn't work on some special files but doesn't return an
609      error, either.  */
610   if (fstat (fd, &stats))
611     {
612       error (0, errno, "%s", filename);
613       return 1;
614     }
615
616   if (from_start)
617     {
618       if (S_ISREG (stats.st_mode))
619         lseek (fd, n_bytes, SEEK_CUR);
620       else if (start_bytes (filename, fd, n_bytes))
621         return 1;
622       dump_remainder (filename, fd);
623     }
624   else
625     {
626       if (S_ISREG (stats.st_mode))
627         {
628           off_t current_pos, end_pos;
629           size_t bytes_remaining;
630
631           if ((current_pos = lseek (fd, (off_t) 0, SEEK_CUR)) != -1
632               && (end_pos = lseek (fd, (off_t) 0, SEEK_END)) != -1)
633             {
634               off_t diff;
635               /* Be careful here.  The current position may actually be
636                  beyond the end of the file.  */
637               bytes_remaining = (diff = end_pos - current_pos) < 0 ? 0 : diff;
638             }
639           else
640             {
641               error (0, errno, "%s", filename);
642               return 1;
643             }
644
645           if (bytes_remaining <= n_bytes)
646             {
647               /* From the current position to end of file, there are no
648                  more bytes than have been requested.  So reposition the
649                  file pointer to the incoming current position and print
650                  everything after that.  */
651               lseek (fd, current_pos, SEEK_SET);
652             }
653           else
654             {
655               /* There are more bytes remaining than were requested.
656                  Back up.  */
657               lseek (fd, -n_bytes, SEEK_END);
658             }
659           dump_remainder (filename, fd);
660         }
661       else
662         return pipe_bytes (filename, fd, n_bytes);
663     }
664   return 0;
665 }
666
667 /* Output the last N_LINES lines of file FILENAME open for reading in FD.
668    Return 0 if successful, 1 if an error occurred.  */
669
670 static int
671 tail_lines (const char *filename, int fd, long int n_lines)
672 {
673   struct stat stats;
674   off_t length;
675
676   if (fstat (fd, &stats))
677     {
678       error (0, errno, "%s", filename);
679       return 1;
680     }
681
682   if (from_start)
683     {
684       if (start_lines (filename, fd, n_lines))
685         return 1;
686       dump_remainder (filename, fd);
687     }
688   else
689     {
690       /* Use file_lines only if FD refers to a regular file with
691          its file pointer positioned at beginning of file.  */
692       /* FIXME: adding the lseek conjunct is a kludge.
693          Once there's a reasonable test suite, fix the true culprit:
694          file_lines.  file_lines shouldn't presume that the input
695          file pointer is initially positioned to beginning of file.  */
696       if (S_ISREG (stats.st_mode)
697           && lseek (fd, (off_t) 0, SEEK_CUR) == (off_t) 0)
698         {
699           length = lseek (fd, (off_t) 0, SEEK_END);
700           if (length != 0 && file_lines (filename, fd, n_lines, length))
701             return 1;
702           dump_remainder (filename, fd);
703         }
704       else
705         return pipe_lines (filename, fd, n_lines);
706     }
707   return 0;
708 }
709
710 /* Display the last N_UNITS units of file FILENAME, open for reading
711    in FD.
712    Return 0 if successful, 1 if an error occurred.  */
713
714 static int
715 tail (const char *filename, int fd, off_t n_units)
716 {
717   if (count_lines)
718     return tail_lines (filename, fd, (long) n_units);
719   else
720     return tail_bytes (filename, fd, n_units);
721 }
722
723 /* Display the last N_UNITS units of file FILENAME.
724    "-" for FILENAME means the standard input.
725    FILENUM is this file's index in the list of files the user gave.
726    Return 0 if successful, 1 if an error occurred.  */
727
728 static int
729 tail_file (const char *filename, off_t n_units, int filenum)
730 {
731   int fd, errors;
732   struct stat stats;
733
734   if (!strcmp (filename, "-")
735     {
736       have_read_stdin = 1;
737       filename = "standard input";
738       if (print_headers)
739         write_header (filename, NULL);
740       errors = tail (filename, 0, n_units);
741       if (forever_multiple)
742         {
743           if (fstat (0, &stats) < 0)
744             {
745               error (0, errno, "standard input");
746               errors = 1;
747             }
748           else if (!S_ISREG (stats.st_mode))
749             {
750               error (0, 0,
751                      "standard input: cannot follow end of non-regular file");
752               errors = 1;
753             }
754           if (errors)
755             file_descs[filenum] = -1;
756           else
757             {
758               file_descs[filenum] = 0;
759               file_sizes[filenum] = stats.st_size;
760             }
761         }
762     }
763   else
764     {
765       /* Not standard input.  */
766       fd = open (filename, O_RDONLY);
767       if (fd == -1)
768         {
769           if (forever_multiple)
770             file_descs[filenum] = -1;
771           error (0, errno, "%s", filename);
772           errors = 1;
773         }
774       else
775         {
776           if (print_headers)
777             write_header (filename, NULL);
778           errors = tail (filename, fd, n_units);
779           if (forever_multiple)
780             {
781               if (fstat (fd, &stats) < 0)
782                 {
783                   error (0, errno, "%s", filename);
784                   errors = 1;
785                 }
786               else if (!S_ISREG (stats.st_mode))
787                 {
788                   error (0, 0, "%s: cannot follow end of non-regular file",
789                          filename);
790                   errors = 1;
791                 }
792               if (errors)
793                 {
794                   close (fd);
795                   file_descs[filenum] = -1;
796                 }
797               else
798                 {
799                   file_descs[filenum] = fd;
800                   file_sizes[filenum] = stats.st_size;
801                 }
802             }
803           else
804             {
805               if (close (fd))
806                 {
807                   error (0, errno, "%s", filename);
808                   errors = 1;
809                 }
810             }
811         }
812     }
813
814   return errors;
815 }
816
817 extern int
818 tai_main (int argc, char **argv)
819 {
820   enum header_mode header_mode = multiple_files;
821   int exit_status = 0;
822   /* If from_start, the number of items to skip before printing; otherwise,
823      the number of items at the end of the file to print.  Initially, -1
824      means the value has not been set.  */
825   off_t n_units = -1;
826   long int tmp_long;
827   int c;                        /* Option character.  */
828   int n_files;
829   char **file;
830
831   program_name = argv[0];
832   have_read_stdin = 0;
833   count_lines = 1;
834   forever = forever_multiple = from_start = print_headers = 0;
835
836   if (argc > 1
837       && ((argv[1][0] == '-' && ISDIGIT (argv[1][1]))
838           || (argv[1][0] == '+' && (ISDIGIT (argv[1][1])
839                                     || argv[1][1] == 0))))
840     {
841       /* Old option syntax: a dash or plus, one or more digits (zero digits
842          are acceptable with a plus), and one or more option letters.  */
843       if (argv[1][0] == '+')
844         from_start = 1;
845       if (argv[1][1] != '\0')
846         {
847           strtol_error s_err;
848           char *p;
849
850           s_err = xstrtol (++argv[1], &p, 0, &tmp_long, "bkm");
851           n_units = tmp_long;
852           if (s_err == LONGINT_OVERFLOW)
853             {
854               STRTOL_FATAL_ERROR (argv[1], "argument", s_err);
855             }
856
857           /* If a [bkm] suffix was given then count bytes, not lines.  */
858           if (p[-1] == 'b' || p[-1] == 'k' || p[-1] == 'm')
859             count_lines = 0;
860
861           /* Parse any appended option letters.  */
862           while (*p)
863             {
864               switch (*p)
865                 {
866                 case 'c':
867                   /* Interpret N_UNITS as # of bytes.  */
868                   count_lines = 0;
869                   break;
870
871                 case 'f':
872                   forever = 1;
873                   break;
874
875                 case 'l':
876                   count_lines = 1;
877                   break;
878
879                 case 'q':
880                   header_mode = never;
881                   break;
882
883                 case 'v':
884                   header_mode = always;
885                   break;
886
887                 default:
888                   error (0, 0, "unrecognized option '%c'", *p);
889                   usage (tail_usage);
890                 }
891               ++p;
892             }
893         }
894       /* Make the options we just parsed invisible to getopt.  */
895       argv[1] = argv[0];
896       argv++;
897       argc--;
898     }
899
900   if (show_version)
901     {
902       printf ("tail - %s\n", PACKAGE_VERSION);
903       exit (EXIT_SUCCESS);
904     }
905
906   if (show_help)
907     usage (tail_usage);
908
909   if (n_units == -1)
910     n_units = DEFAULT_N_LINES;
911
912   /* To start printing with item N_UNITS from the start of the file, skip
913      N_UNITS - 1 items.  `tail +0' is actually meaningless, but for Unix
914      compatibility it's treated the same as `tail +1'.  */
915   if (from_start)
916     {
917       if (n_units)
918         --n_units;
919     }
920
921   n_files = argc - optind;
922   file = argv + optind;
923
924   if (n_files > 1 && forever)
925     {
926       forever_multiple = 1;
927       forever = 0;
928       file_descs = (int *) xmalloc (n_files * sizeof (int));
929       file_sizes = (off_t *) xmalloc (n_files * sizeof (off_t));
930     }
931
932   if (header_mode == always
933       || (header_mode == multiple_files && n_files > 1))
934     print_headers = 1;
935
936   if (n_files == 0)
937     {
938       exit_status |= tail_file ("-", n_units, 0);
939     }
940   else
941     {
942       int i;
943       for (i = 0; i < n_files; i++)
944         exit_status |= tail_file (file[i], n_units, i);
945
946       if (forever_multiple)
947         tail_forever (file, n_files);
948     }
949
950   if (have_read_stdin && close (0) < 0)
951     error (EXIT_FAILURE, errno, "-");
952   if (fclose (stdout) == EOF)
953     error (EXIT_FAILURE, errno, "write error");
954   exit (exit_status == 0 ? EXIT_SUCCESS : EXIT_FAILURE);
955 }