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