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