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