[struct File_spec] (pretty_name): Remove member.
[platform/upstream/coreutils.git] / src / tail.c
1 /* tail -- output the last part of file(s)
2    Copyright (C) 89, 90, 91, 95, 96, 1997, 1998 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    Original version by Paul Rubin <phr@ocf.berkeley.edu>.
23    Extensions by David MacKenzie <djm@gnu.ai.mit.edu>.
24    tail -f for multiple files by Ian Lance Taylor <ian@airs.com>.  */
25
26 #include <config.h>
27
28 #include <stdio.h>
29 #include <assert.h>
30 #include <getopt.h>
31 #include <sys/types.h>
32
33 #include "system.h"
34 #include "xstrtoul.h"
35 #include "error.h"
36 #include "safe-read.h"
37
38 #ifndef OFF_T_MIN
39 # define OFF_T_MIN TYPE_MINIMUM (off_t)
40 #endif
41
42 #ifndef OFF_T_MAX
43 # define OFF_T_MAX TYPE_MAXIMUM (off_t)
44 #endif
45
46 /* Number of items to tail.  */
47 #define DEFAULT_N_LINES 10
48
49 /* Size of atomic reads.  */
50 #ifndef BUFSIZ
51 # define BUFSIZ (512 * 8)
52 #endif
53
54 enum Follow_mode
55 {
56   /* FIXME: describe */
57   follow_name,
58
59   /* FIXME: describe */
60   follow_descriptor,
61 };
62
63 struct File_spec
64 {
65   /* The actual file name, or "-" for stdin.  */
66   char *name;
67
68   /* File descriptor on which the file is open; -1 if it's not open.  */
69   int fd;
70
71   /* The size of the file the last time we checked.  */
72   off_t size;
73
74   /* The device and inode of the file the last time we checked.  */
75   dev_t dev;
76   ino_t ino;
77
78   /* FIXME: describe */
79   unsigned int n_stat_calls;
80
81   /* FIXME: describe */
82   unsigned int n_unchanged_stats;
83
84   /* FIXME: describe */
85   int missing;
86 };
87
88 /* FIXME: describe */
89 static int allow_missing;
90
91 /* If nonzero, interpret the numeric argument as the number of lines.
92    Otherwise, interpret it as the number of bytes.  */
93 static int count_lines;
94
95 /* Whether we follow the name of each file or the file descriptor
96    that is initially associated with each name.  */
97 /* FIXME: make follow_name the default? */
98 static enum Follow_mode follow_mode;
99
100 /* If nonzero, read from the ends of all specified files until killed.  */
101 static int forever;
102
103 /* If nonzero, count from start of file instead of end.  */
104 static int from_start;
105
106 /* If nonzero, print filename headers.  */
107 static int print_headers;
108
109 /* When to print the filename banners.  */
110 enum header_mode
111 {
112   multiple_files, always, never
113 };
114
115 /* FIXME: describe -- add option */
116 static unsigned long max_n_unchanged_stats = 5;
117
118 /* The name this program was run with.  */
119 char *program_name;
120
121 /* The number of seconds to sleep between accesses.  */
122 static unsigned int sleep_interval = 1;
123
124 /* Nonzero if we have ever read standard input.  */
125 static int have_read_stdin;
126
127 /* If nonzero, display usage information and exit.  */
128 static int show_help;
129
130 /* If nonzero, print the version on standard output then exit.  */
131 static int show_version;
132
133 static struct option const long_options[] =
134 {
135   {"allow-missing", required_argument, NULL, 11},
136   {"bytes", required_argument, NULL, 'c'},
137   {"follow", no_argument, NULL, 'f'},
138   {"follow-descriptor", no_argument, NULL, 12},
139   {"follow-name", no_argument, NULL, 13},
140   {"lines", required_argument, NULL, 'n'},
141   {"quiet", no_argument, NULL, 'q'},
142   {"silent", no_argument, NULL, 'q'},
143   {"sleep-interval", required_argument, NULL, 's'},
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   -s, --sleep-interval=S   with -f, sleep S seconds between iterations\n\
172   -v, --verbose            always output headers giving file names\n\
173       --help               display this help and exit\n\
174       --version            output version information and exit\n\
175 \n\
176 If the first character of N (the number of bytes or lines) is a `+',\n\
177 print beginning with the Nth item from the start of each file, otherwise,\n\
178 print the last N items in the file.  N may have a multiplier suffix:\n\
179 b for 512, k for 1024, m for 1048576 (1 Meg).  A first OPTION of -VALUE\n\
180 or +VALUE is treated like -n VALUE or -n +VALUE unless VALUE has one of\n\
181 the [bkm] suffix multipliers, in which case it is treated like -c VALUE\n\
182 or -c +VALUE.\n\
183 "));
184       puts (_("\nReport bugs to <textutils-bugs@gnu.org>."));
185     }
186   exit (status == 0 ? EXIT_SUCCESS : EXIT_FAILURE);
187 }
188
189 static char *
190 pretty_name (struct File_spec const *f)
191 {
192   return (STREQ (f->name, "-") ? "standard input" : f->name);
193 }
194
195 static void
196 xwrite (int fd, char *const buffer, size_t n_bytes)
197 {
198   assert (fd == 1);
199   assert (n_bytes >= 0);
200   if (n_bytes > 0 && fwrite (buffer, 1, n_bytes, stdout) == 0)
201     error (EXIT_FAILURE, errno, _("write error"));
202 }
203
204 static void
205 close_fd (int fd, const char *filename)
206 {
207   if (fd != -1 && fd != STDIN_FILENO && close (fd))
208     {
209       error (0, errno, _("closing %s (fd=%d)"), filename, fd);
210     }
211 }
212
213 static void
214 write_header (const char *pretty_filename, const char *comment)
215 {
216   static int first_file = 1;
217
218   printf ("%s==> %s%s%s <==\n", (first_file ? "" : "\n"), pretty_filename,
219           (comment ? ": " : ""),
220           (comment ? comment : ""));
221   first_file = 0;
222 }
223
224 /* Print the last N_LINES lines from the end of file FD.
225    Go backward through the file, reading `BUFSIZ' bytes at a time (except
226    probably the first), until we hit the start of the file or have
227    read NUMBER newlines.
228    POS starts out as the length of the file (the offset of the last
229    byte of the file + 1).
230    Return 0 if successful, 1 if an error occurred.  */
231
232 static int
233 file_lines (const char *pretty_filename, int fd, long int n_lines, off_t pos)
234 {
235   char buffer[BUFSIZ];
236   int bytes_read;
237   int i;                        /* Index into `buffer' for scanning.  */
238
239   if (n_lines == 0)
240     return 0;
241
242   /* Set `bytes_read' to the size of the last, probably partial, buffer;
243      0 < `bytes_read' <= `BUFSIZ'.  */
244   bytes_read = pos % BUFSIZ;
245   if (bytes_read == 0)
246     bytes_read = BUFSIZ;
247   /* Make `pos' a multiple of `BUFSIZ' (0 if the file is short), so that all
248      reads will be on block boundaries, which might increase efficiency.  */
249   pos -= bytes_read;
250   /* FIXME: check lseek return value  */
251   lseek (fd, pos, SEEK_SET);
252   bytes_read = safe_read (fd, buffer, bytes_read);
253   if (bytes_read == -1)
254     {
255       error (0, errno, "%s", pretty_filename);
256       return 1;
257     }
258
259   /* Count the incomplete line on files that don't end with a newline.  */
260   if (bytes_read && buffer[bytes_read - 1] != '\n')
261     --n_lines;
262
263   do
264     {
265       /* Scan backward, counting the newlines in this bufferfull.  */
266       for (i = bytes_read - 1; i >= 0; i--)
267         {
268           /* Have we counted the requested number of newlines yet?  */
269           if (buffer[i] == '\n' && n_lines-- == 0)
270             {
271               /* If this newline wasn't the last character in the buffer,
272                  print the text after it.  */
273               if (i != bytes_read - 1)
274                 xwrite (STDOUT_FILENO, &buffer[i + 1], bytes_read - (i + 1));
275               return 0;
276             }
277         }
278       /* Not enough newlines in that bufferfull.  */
279       if (pos == 0)
280         {
281           /* Not enough lines in the file; print the entire file.  */
282           /* FIXME: check lseek return value  */
283           lseek (fd, (off_t) 0, SEEK_SET);
284           return 0;
285         }
286       pos -= BUFSIZ;
287       /* FIXME: check lseek return value  */
288       lseek (fd, pos, SEEK_SET);
289     }
290   while ((bytes_read = safe_read (fd, buffer, BUFSIZ)) > 0);
291   if (bytes_read == -1)
292     {
293       error (0, errno, "%s", pretty_filename);
294       return 1;
295     }
296   return 0;
297 }
298
299 /* Print the last N_LINES lines from the end of the standard input,
300    open for reading as pipe FD.
301    Buffer the text as a linked list of LBUFFERs, adding them as needed.
302    Return 0 if successful, 1 if an error occured.  */
303
304 static int
305 pipe_lines (const char *pretty_filename, int fd, long int n_lines)
306 {
307   struct linebuffer
308   {
309     int nbytes, nlines;
310     char buffer[BUFSIZ];
311     struct linebuffer *next;
312   };
313   typedef struct linebuffer LBUFFER;
314   LBUFFER *first, *last, *tmp;
315   int i;                        /* Index into buffers.  */
316   int total_lines = 0;          /* Total number of newlines in all buffers.  */
317   int errors = 0;
318
319   first = last = (LBUFFER *) xmalloc (sizeof (LBUFFER));
320   first->nbytes = first->nlines = 0;
321   first->next = NULL;
322   tmp = (LBUFFER *) xmalloc (sizeof (LBUFFER));
323
324   /* Input is always read into a fresh buffer.  */
325   while ((tmp->nbytes = safe_read (fd, tmp->buffer, BUFSIZ)) > 0)
326     {
327       tmp->nlines = 0;
328       tmp->next = NULL;
329
330       /* Count the number of newlines just read.  */
331       for (i = 0; i < tmp->nbytes; i++)
332         if (tmp->buffer[i] == '\n')
333           ++tmp->nlines;
334       total_lines += tmp->nlines;
335
336       /* If there is enough room in the last buffer read, just append the new
337          one to it.  This is because when reading from a pipe, `nbytes' can
338          often be very small.  */
339       if (tmp->nbytes + last->nbytes < BUFSIZ)
340         {
341           memcpy (&last->buffer[last->nbytes], tmp->buffer, tmp->nbytes);
342           last->nbytes += tmp->nbytes;
343           last->nlines += tmp->nlines;
344         }
345       else
346         {
347           /* If there's not enough room, link the new buffer onto the end of
348              the list, then either free up the oldest buffer for the next
349              read if that would leave enough lines, or else malloc a new one.
350              Some compaction mechanism is possible but probably not
351              worthwhile.  */
352           last = last->next = tmp;
353           if (total_lines - first->nlines > n_lines)
354             {
355               tmp = first;
356               total_lines -= first->nlines;
357               first = first->next;
358             }
359           else
360             tmp = (LBUFFER *) xmalloc (sizeof (LBUFFER));
361         }
362     }
363   if (tmp->nbytes == -1)
364     {
365       error (0, errno, "%s", pretty_filename);
366       errors = 1;
367       free ((char *) tmp);
368       goto free_lbuffers;
369     }
370
371   free ((char *) tmp);
372
373   /* This prevents a core dump when the pipe contains no newlines.  */
374   if (n_lines == 0)
375     goto free_lbuffers;
376
377   /* Count the incomplete line on files that don't end with a newline.  */
378   if (last->buffer[last->nbytes - 1] != '\n')
379     {
380       ++last->nlines;
381       ++total_lines;
382     }
383
384   /* Run through the list, printing lines.  First, skip over unneeded
385      buffers.  */
386   for (tmp = first; total_lines - tmp->nlines > n_lines; tmp = tmp->next)
387     total_lines -= tmp->nlines;
388
389   /* Find the correct beginning, then print the rest of the file.  */
390   if (total_lines > n_lines)
391     {
392       char *cp;
393
394       /* Skip `total_lines' - `n_lines' newlines.  We made sure that
395          `total_lines' - `n_lines' <= `tmp->nlines'.  */
396       cp = tmp->buffer;
397       for (i = total_lines - n_lines; i; --i)
398         while (*cp++ != '\n')
399           /* Do nothing.  */ ;
400       i = cp - tmp->buffer;
401     }
402   else
403     i = 0;
404   xwrite (STDOUT_FILENO, &tmp->buffer[i], tmp->nbytes - i);
405
406   for (tmp = tmp->next; tmp; tmp = tmp->next)
407     xwrite (STDOUT_FILENO, tmp->buffer, tmp->nbytes);
408
409 free_lbuffers:
410   while (first)
411     {
412       tmp = first->next;
413       free ((char *) first);
414       first = tmp;
415     }
416   return errors;
417 }
418
419 /* Print the last N_BYTES characters from the end of pipe FD.
420    This is a stripped down version of pipe_lines.
421    Return 0 if successful, 1 if an error occurred.  */
422
423 static int
424 pipe_bytes (const char *pretty_filename, int fd, off_t n_bytes)
425 {
426   struct charbuffer
427   {
428     int nbytes;
429     char buffer[BUFSIZ];
430     struct charbuffer *next;
431   };
432   typedef struct charbuffer CBUFFER;
433   CBUFFER *first, *last, *tmp;
434   int i;                        /* Index into buffers.  */
435   int total_bytes = 0;          /* Total characters in all buffers.  */
436   int errors = 0;
437
438   first = last = (CBUFFER *) xmalloc (sizeof (CBUFFER));
439   first->nbytes = 0;
440   first->next = NULL;
441   tmp = (CBUFFER *) xmalloc (sizeof (CBUFFER));
442
443   /* Input is always read into a fresh buffer.  */
444   while ((tmp->nbytes = safe_read (fd, tmp->buffer, BUFSIZ)) > 0)
445     {
446       tmp->next = NULL;
447
448       total_bytes += tmp->nbytes;
449       /* If there is enough room in the last buffer read, just append the new
450          one to it.  This is because when reading from a pipe, `nbytes' can
451          often be very small.  */
452       if (tmp->nbytes + last->nbytes < BUFSIZ)
453         {
454           memcpy (&last->buffer[last->nbytes], tmp->buffer, tmp->nbytes);
455           last->nbytes += tmp->nbytes;
456         }
457       else
458         {
459           /* If there's not enough room, link the new buffer onto the end of
460              the list, then either free up the oldest buffer for the next
461              read if that would leave enough characters, or else malloc a new
462              one.  Some compaction mechanism is possible but probably not
463              worthwhile.  */
464           last = last->next = tmp;
465           if (total_bytes - first->nbytes > n_bytes)
466             {
467               tmp = first;
468               total_bytes -= first->nbytes;
469               first = first->next;
470             }
471           else
472             {
473               tmp = (CBUFFER *) xmalloc (sizeof (CBUFFER));
474             }
475         }
476     }
477   if (tmp->nbytes == -1)
478     {
479       error (0, errno, "%s", pretty_filename);
480       errors = 1;
481       free ((char *) tmp);
482       goto free_cbuffers;
483     }
484
485   free ((char *) tmp);
486
487   /* Run through the list, printing characters.  First, skip over unneeded
488      buffers.  */
489   for (tmp = first; total_bytes - tmp->nbytes > n_bytes; tmp = tmp->next)
490     total_bytes -= tmp->nbytes;
491
492   /* Find the correct beginning, then print the rest of the file.
493      We made sure that `total_bytes' - `n_bytes' <= `tmp->nbytes'.  */
494   if (total_bytes > n_bytes)
495     i = total_bytes - n_bytes;
496   else
497     i = 0;
498   xwrite (STDOUT_FILENO, &tmp->buffer[i], tmp->nbytes - i);
499
500   for (tmp = tmp->next; tmp; tmp = tmp->next)
501     xwrite (STDOUT_FILENO, tmp->buffer, tmp->nbytes);
502
503 free_cbuffers:
504   while (first)
505     {
506       tmp = first->next;
507       free ((char *) first);
508       first = tmp;
509     }
510   return errors;
511 }
512
513 /* Skip N_BYTES characters from the start of pipe FD, and print
514    any extra characters that were read beyond that.
515    Return 1 on error, 0 if ok.  */
516
517 static int
518 start_bytes (const char *pretty_filename, int fd, off_t n_bytes)
519 {
520   char buffer[BUFSIZ];
521   int bytes_read = 0;
522
523   while (n_bytes > 0 && (bytes_read = safe_read (fd, buffer, BUFSIZ)) > 0)
524     n_bytes -= bytes_read;
525   if (bytes_read == -1)
526     {
527       error (0, errno, "%s", pretty_filename);
528       return 1;
529     }
530   else if (n_bytes < 0)
531     xwrite (STDOUT_FILENO, &buffer[bytes_read + n_bytes], -n_bytes);
532   return 0;
533 }
534
535 /* Skip N_LINES lines at the start of file or pipe FD, and print
536    any extra characters that were read beyond that.
537    Return 1 on error, 0 if ok.  */
538
539 static int
540 start_lines (const char *pretty_filename, int fd, long int n_lines)
541 {
542   char buffer[BUFSIZ];
543   int bytes_read = 0;
544   int bytes_to_skip = 0;
545
546   while (n_lines && (bytes_read = safe_read (fd, buffer, BUFSIZ)) > 0)
547     {
548       bytes_to_skip = 0;
549       while (bytes_to_skip < bytes_read)
550         if (buffer[bytes_to_skip++] == '\n' && --n_lines == 0)
551           break;
552     }
553   if (bytes_read == -1)
554     {
555       error (0, errno, "%s", pretty_filename);
556       return 1;
557     }
558   else if (bytes_to_skip < bytes_read)
559     {
560       xwrite (STDOUT_FILENO, &buffer[bytes_to_skip],
561               bytes_read - bytes_to_skip);
562     }
563   return 0;
564 }
565
566 /* Display file FILENAME from the current position in FD to the end.
567    Return the number of bytes read from the file.  */
568
569 static long
570 dump_remainder (const char *pretty_filename, int fd)
571 {
572   char buffer[BUFSIZ];
573   int bytes_read;
574   long total;
575
576   total = 0;
577   while ((bytes_read = safe_read (fd, buffer, BUFSIZ)) > 0)
578     {
579       xwrite (STDOUT_FILENO, buffer, bytes_read);
580       total += bytes_read;
581     }
582   if (bytes_read == -1)
583     error (EXIT_FAILURE, errno, "%s", pretty_filename);
584
585   if (forever)
586     fflush (stdout);
587
588   return total;
589 }
590
591 /* FIXME: describe */
592
593 static void
594 recheck (struct File_spec *f)
595 {
596   /* open/fstat the file and announce if dev/ino
597      have changed */
598   struct stat new_stats;
599   int fd;
600   int fail = 0;
601   int is_stdin = (STREQ (f->name, "-"));
602
603   fd = (is_stdin ? STDIN_FILENO : open (f->name, O_RDONLY));
604
605   /* If the open fails because the file doesn't exist,
606      then mark the file as missing.  */
607   f->missing = (allow_missing && fd == -1 && errno == ENOENT);
608
609   if (fd == -1 || fstat (fd, &new_stats) < 0)
610     {
611       fail = 1;
612       error (0, errno, "%s", pretty_name (f));
613     }
614   else if (!S_ISREG (new_stats.st_mode)
615            && !S_ISFIFO (new_stats.st_mode))
616     {
617       fail = 1;
618       error (0, 0,
619              _("%s has been replaced with a non-regular file;  \
620 cannot follow end of non-regular file"),
621              pretty_name (f));
622     }
623
624   if (fail)
625     {
626       close_fd (fd, pretty_name (f));
627       close_fd (f->fd, pretty_name (f));
628       f->fd = -1;
629     }
630   else if (f->ino != new_stats.st_ino || f->dev != new_stats.st_dev)
631     {
632       /* Close the old one.  */
633       close_fd (f->fd, pretty_name (f));
634
635       /* File has been replaced (e.g., via log rotation) --
636          tail the new one.  */
637       error (0, 0,
638              _("%s has been replaced;  following end of new file"),
639              pretty_name (f));
640
641       f->fd = fd;
642       f->size = new_stats.st_size;
643       f->dev = new_stats.st_dev;
644       f->ino = new_stats.st_ino;
645       f->n_unchanged_stats = 0;
646       /* FIXME: check lseek return value  */
647       lseek (f->fd, new_stats.st_size, SEEK_SET);
648     }
649   else if (f->missing)
650     {
651       error (0, 0, _("%s has reappeared"), pretty_name (f));
652       f->missing = 0;
653
654       f->fd = fd;
655       f->size = new_stats.st_size;
656       f->dev = new_stats.st_dev;
657       f->ino = new_stats.st_ino;
658       f->n_unchanged_stats = 0;
659       /* FIXME: check lseek return value  */
660       lseek (f->fd, new_stats.st_size, SEEK_SET);
661     }
662   else
663     {
664       close_fd (fd, pretty_name (f));
665     }
666 }
667
668 /* Tail NFILES files forever, or until killed.
669    The pertinent information for each file is stored in an entry of F.
670    Loop over each of them, doing an fstat to see if they have changed size,
671    and an occasional open/fstat to see if any dev/ino pair has changed.
672    If none of them have changed size in one iteration, sleep for a
673    while and try again.  Continue until the user interrupts us.  */
674
675 static void
676 tail_forever (struct File_spec *f, int nfiles)
677 {
678   int last;
679
680   last = nfiles - 1;
681
682   while (1)
683     {
684       int i;
685       int any_changed;
686       int any_live_files;
687
688       any_live_files = 0;
689       any_changed = 0;
690       for (i = 0; i < nfiles; i++)
691         {
692           struct stat stats;
693
694           if (f[i].fd < 0 && !f[i].missing)
695             continue;
696
697           any_live_files = 1;
698
699           if (fstat (f[i].fd, &stats) < 0)
700             {
701               error (0, errno, "%s", pretty_name (&f[i]));
702               f[i].fd = -1;
703               continue;
704             }
705
706           if (stats.st_size == f[i].size)
707             {
708               if (++f[i].n_unchanged_stats > max_n_unchanged_stats
709                   && follow_mode == follow_name)
710                 {
711                   recheck (&f[i]);
712                   f[i].n_unchanged_stats = 0;
713                 }
714
715               continue;
716             }
717
718           /* FIXME-now:
719              Otherwise, a file that's unlinked or moved aside, yet always
720              growing will never be recognized has having been renamed.  */
721
722           /* This file has changed size.  Print out what we can, and
723              then keep looping.  */
724
725           any_changed = 1;
726
727           /* reset counter */
728           f[i].n_unchanged_stats = 0;
729
730           if (stats.st_size < f[i].size)
731             {
732               write_header (pretty_name (&f[i]), _("file truncated"));
733               last = i;
734               /* FIXME: check lseek return value  */
735               lseek (f[i].fd, stats.st_size, SEEK_SET);
736               f[i].size = stats.st_size;
737               continue;
738             }
739
740           if (i != last)
741             {
742               if (print_headers)
743                 write_header (pretty_name (&f[i]), NULL);
744               last = i;
745             }
746           f[i].size += dump_remainder (pretty_name (&f[i]), f[i].fd);
747         }
748
749       if (!any_live_files /* FIXME-now: && ! allow_missing */ )
750         {
751           error (0, 0, _("no files remaining"));
752           break;
753         }
754
755       /* If none of the files changed size, sleep.  */
756       if (!any_changed)
757         sleep (sleep_interval);
758     }
759 }
760
761 /* Output the last N_BYTES bytes of file FILENAME open for reading in FD.
762    Return 0 if successful, 1 if an error occurred.  */
763
764 static int
765 tail_bytes (const char *pretty_filename, int fd, off_t n_bytes)
766 {
767   struct stat stats;
768
769   /* FIXME: resolve this like in dd.c.  */
770   /* Use fstat instead of checking for errno == ESPIPE because
771      lseek doesn't work on some special files but doesn't return an
772      error, either.  */
773   if (fstat (fd, &stats))
774     {
775       error (0, errno, "%s", pretty_filename);
776       return 1;
777     }
778
779   if (from_start)
780     {
781       if (S_ISREG (stats.st_mode))
782         {
783           /* FIXME: check lseek return value  */
784           lseek (fd, n_bytes, SEEK_CUR);
785         }
786       else if (start_bytes (pretty_filename, fd, n_bytes))
787         {
788           return 1;
789         }
790       dump_remainder (pretty_filename, fd);
791     }
792   else
793     {
794       if (S_ISREG (stats.st_mode))
795         {
796           off_t current_pos, end_pos;
797           size_t bytes_remaining;
798
799           if ((current_pos = lseek (fd, (off_t) 0, SEEK_CUR)) != -1
800               && (end_pos = lseek (fd, (off_t) 0, SEEK_END)) != -1)
801             {
802               off_t diff;
803               /* Be careful here.  The current position may actually be
804                  beyond the end of the file.  */
805               bytes_remaining = (diff = end_pos - current_pos) < 0 ? 0 : diff;
806             }
807           else
808             {
809               error (0, errno, "%s", pretty_filename);
810               return 1;
811             }
812
813           if (bytes_remaining <= n_bytes)
814             {
815               /* From the current position to end of file, there are no
816                  more bytes than have been requested.  So reposition the
817                  file pointer to the incoming current position and print
818                  everything after that.  */
819               /* FIXME: check lseek return value  */
820               lseek (fd, current_pos, SEEK_SET);
821             }
822           else
823             {
824               /* There are more bytes remaining than were requested.
825                  Back up.  */
826               /* FIXME: check lseek return value  */
827               lseek (fd, -n_bytes, SEEK_END);
828             }
829           dump_remainder (pretty_filename, fd);
830         }
831       else
832         return pipe_bytes (pretty_filename, fd, n_bytes);
833     }
834   return 0;
835 }
836
837 /* Output the last N_LINES lines of file FILENAME open for reading in FD.
838    Return 0 if successful, 1 if an error occurred.  */
839
840 static int
841 tail_lines (const char *pretty_filename, int fd, long int n_lines)
842 {
843   struct stat stats;
844   off_t length;
845
846   if (fstat (fd, &stats))
847     {
848       error (0, errno, "%s", pretty_filename);
849       return 1;
850     }
851
852   if (from_start)
853     {
854       if (start_lines (pretty_filename, fd, n_lines))
855         return 1;
856       dump_remainder (pretty_filename, fd);
857     }
858   else
859     {
860       /* Use file_lines only if FD refers to a regular file with
861          its file pointer positioned at beginning of file.  */
862       /* FIXME: adding the lseek conjunct is a kludge.
863          Once there's a reasonable test suite, fix the true culprit:
864          file_lines.  file_lines shouldn't presume that the input
865          file pointer is initially positioned to beginning of file.  */
866       if (S_ISREG (stats.st_mode)
867           && lseek (fd, (off_t) 0, SEEK_CUR) == (off_t) 0)
868         {
869           length = lseek (fd, (off_t) 0, SEEK_END);
870           if (length != 0 && file_lines (pretty_filename, fd, n_lines, length))
871             return 1;
872           dump_remainder (pretty_filename, fd);
873         }
874       else
875         return pipe_lines (pretty_filename, fd, n_lines);
876     }
877   return 0;
878 }
879
880 /* Display the last N_UNITS units of file FILENAME, open for reading
881    in FD.
882    Return 0 if successful, 1 if an error occurred.  */
883
884 static int
885 tail (const char *pretty_filename, int fd, off_t n_units)
886 {
887   if (count_lines)
888     return tail_lines (pretty_filename, fd, (long) n_units);
889   else
890     return tail_bytes (pretty_filename, fd, n_units);
891 }
892
893 /* Display the last N_UNITS units of the file described by F.
894    Return 0 if successful, 1 if an error occurred.  */
895
896 static int
897 tail_file (struct File_spec *f, off_t n_units)
898 {
899   int fd, errors;
900   struct stat stats;
901
902   int is_stdin = (STREQ (f->name, "-"));
903
904   if (is_stdin)
905     {
906       have_read_stdin = 1;
907       fd = STDIN_FILENO;
908     }
909   else
910     {
911       fd = open (f->name, O_RDONLY);
912     }
913
914   f->missing = (allow_missing && fd == -1 && errno == ENOENT);
915
916   if (fd == -1)
917     {
918       if (forever)
919         f->fd = -1;
920       error (0, errno, "%s", pretty_name (f));
921       errors = 1;
922     }
923   else
924     {
925       if (print_headers)
926         write_header (pretty_name (f), NULL);
927       errors = tail (pretty_name (f), fd, n_units);
928       if (forever)
929         {
930           /* FIXME: duplicate code */
931           if (fstat (fd, &stats) < 0)
932             {
933               error (0, errno, "%s", pretty_name (f));
934               errors = 1;
935             }
936           else if (!S_ISREG (stats.st_mode) && !S_ISFIFO (stats.st_mode))
937             {
938               error (0, 0, _("%s: cannot follow end of non-regular file"),
939                      pretty_name (f));
940               errors = 1;
941             }
942           if (errors)
943             {
944               close_fd (fd, pretty_name (f));
945               f->fd = -1;
946             }
947           else
948             {
949               f->fd = fd;
950               f->size = stats.st_size;
951               f->dev = stats.st_dev;
952               f->ino = stats.st_ino;
953               f->n_unchanged_stats = 0;
954             }
955         }
956       else
957         {
958           if (!is_stdin && close (fd))
959             {
960               error (0, errno, "%s", pretty_name (f));
961               errors = 1;
962             }
963         }
964     }
965
966   return errors;
967 }
968
969 /* If the command line arguments are of the obsolescent form and the
970    option string is well-formed, set *FAIL to zero, set *N_UNITS, the
971    globals COUNT_LINES, FOREVER, and FROM_START, and return non-zero.
972    Otherwise, if the command line arguments appear to be of the
973    obsolescent form but the option string is malformed, set *FAIL to
974    non-zero, don't modify any other parameter or global variable, and
975    return non-zero. Otherwise, return zero and don't modify any parameter
976    or global variable.  */
977
978 static int
979 parse_obsolescent_option (int argc, const char *const *argv,
980                           off_t *n_units, int *fail)
981 {
982   const char *p = argv[1];
983   const char *n_string = NULL;
984   const char *n_string_end;
985
986   int t_from_start;
987   int t_count_lines;
988   int t_forever;
989
990   /* With the obsolescent form, there is one option string and
991      (technically) at most one file argument.  But we allow two or more
992      by default.  */
993   if (argc < 2)
994     return 0;
995
996   /* If P starts with `+', `-N' (where N is a digit), or `-l',
997      then it is obsolescent.  Return zero otherwise.  */
998   if ( ! (p[0] == '+' || (p[0] == '-' && (p[1] == 'l' || ISDIGIT (p[1])))) )
999     return 0;
1000
1001   if (*p == '+')
1002     t_from_start = 1;
1003   else if (*p == '-')
1004     t_from_start = 0;
1005   else
1006     return 0;
1007
1008   ++p;
1009   if (ISDIGIT (*p))
1010     {
1011       n_string = p;
1012       do
1013         {
1014           ++p;
1015         }
1016       while (ISDIGIT (*p));
1017     }
1018   n_string_end = p;
1019
1020   t_count_lines = 1;
1021   if (*p == 'c')
1022     {
1023       t_count_lines = 0;
1024       ++p;
1025     }
1026   else if (*p == 'l')
1027     {
1028       ++p;
1029     }
1030
1031   t_forever = 0;
1032   if (*p == 'f')
1033     {
1034       t_forever = 1;
1035       ++p;
1036     }
1037
1038   if (*p != '\0')
1039     {
1040       /* If (argv[1] begins with a `+' or if it begins with `-' followed
1041          by a digit), but has an invalid suffix character, give a diagnostic
1042          and indicate to caller that this *is* of the obsolescent form,
1043          but that it's an invalid option.  */
1044       if (t_from_start || n_string)
1045         {
1046           error (0, 0,
1047                  _("%c: invalid suffix character in obsolescent option" ), *p);
1048           *fail = 1;
1049           return 1;
1050         }
1051
1052       /* Otherwise, it might be a valid non-obsolescent option like -n.  */
1053       return 0;
1054     }
1055
1056   *fail = 0;
1057   if (n_string == NULL)
1058     *n_units = DEFAULT_N_LINES;
1059   else
1060     {
1061       strtol_error s_err;
1062       unsigned long int tmp_ulong;
1063       char *end;
1064       s_err = xstrtoul (n_string, &end, 0, &tmp_ulong, NULL);
1065       if (s_err == LONGINT_OK && tmp_ulong <= OFF_T_MAX)
1066         *n_units = (off_t) tmp_ulong;
1067       else
1068         {
1069           /* Extract a NUL-terminated string for the error message.  */
1070           size_t len = n_string_end - n_string;
1071           char *n_string_tmp = xmalloc (len + 1);
1072
1073           strncpy (n_string_tmp, n_string, len);
1074           n_string_tmp[len] = '\0';
1075
1076           error (0, 0,
1077                  _("%s: %s is so large that it is not representable"),
1078                  n_string_tmp, (count_lines
1079                                 ? _("number of lines")
1080                                 : _("number of bytes")));
1081           free (n_string_tmp);
1082           *fail = 1;
1083         }
1084     }
1085
1086   if (!*fail)
1087     {
1088       if (argc > 3)
1089         {
1090           int posix_pedantic = (getenv ("POSIXLY_CORRECT") != NULL);
1091
1092           /* When POSIXLY_CORRECT is set, enforce the `at most one
1093              file argument' requirement.  */
1094           if (posix_pedantic)
1095             {
1096               error (0, 0, _("\
1097 too many arguments;  When using tail's obsolescent option syntax (%s)\n\
1098 there may be no more than one file argument.  Use the equivalent -n or -c\n\
1099 option instead."), argv[1]);
1100               *fail = 1;
1101               return 1;
1102             }
1103
1104 #if DISABLED  /* FIXME: enable or remove this warning.  */
1105           error (0, 0, _("\
1106 Warning: it is not portable to use two or more file arguments with\n\
1107 tail's obsolescent option syntax (%s).  Use the equivalent -n or -c\n\
1108 option instead."), argv[1]);
1109 #endif
1110         }
1111
1112       /* Set globals.  */
1113       from_start = t_from_start;
1114       count_lines = t_count_lines;
1115       forever = t_forever;
1116     }
1117
1118   return 1;
1119 }
1120
1121 static void
1122 parse_options (int argc, char **argv,
1123                off_t *n_units, enum header_mode *header_mode)
1124 {
1125   int c;
1126
1127   count_lines = 1;
1128   forever = from_start = print_headers = 0;
1129
1130   while ((c = getopt_long (argc, argv, "c:n:fqs:v", long_options, NULL)) != -1)
1131     {
1132       switch (c)
1133         {
1134         case 0:
1135           break;
1136
1137         case 'c':
1138         case 'n':
1139           count_lines = (c == 'n');
1140           if (*optarg == '+')
1141             from_start = 1;
1142           else if (*optarg == '-')
1143             ++optarg;
1144
1145           {
1146             strtol_error s_err;
1147             unsigned long int tmp_ulong;
1148             s_err = xstrtoul (optarg, NULL, 0, &tmp_ulong, "bkm");
1149             if (s_err == LONGINT_INVALID)
1150               {
1151                 error (EXIT_FAILURE, 0, "%s: %s", optarg,
1152                        (c == 'n'
1153                         ? _("invalid number of lines")
1154                         : _("invalid number of bytes")));
1155               }
1156             if (s_err != LONGINT_OK || tmp_ulong > OFF_T_MAX)
1157               {
1158                 error (EXIT_FAILURE, 0,
1159                        _("%s: %s is so large that it is not representable"),
1160                        optarg,
1161                        c == 'n' ? _("number of lines") : _("number of bytes"));
1162               }
1163             *n_units = (off_t) tmp_ulong;
1164           }
1165           break;
1166
1167         case 'f':
1168           forever = 1;
1169           break;
1170
1171         case 11:
1172           allow_missing = 1;
1173           break;
1174
1175         case 12:
1176           follow_mode = follow_descriptor;
1177           break;
1178
1179         case 13:
1180           follow_mode = follow_name;
1181           break;
1182
1183         case 'q':
1184           *header_mode = never;
1185           break;
1186
1187         case 's':
1188           {
1189             strtol_error s_err;
1190             unsigned long int tmp_ulong;
1191             s_err = xstrtoul (optarg, NULL, 0, &tmp_ulong, "");
1192             if (s_err != LONGINT_OK || tmp_ulong > UINT_MAX)
1193               {
1194                 error (EXIT_FAILURE, 0,
1195                        _("%s: invalid number of seconds"), optarg);
1196               }
1197             sleep_interval = tmp_ulong;
1198           }
1199           break;
1200
1201         case 'v':
1202           *header_mode = always;
1203           break;
1204
1205         default:
1206           usage (1);
1207         }
1208     }
1209 }
1210
1211 int
1212 main (int argc, char **argv)
1213 {
1214   enum header_mode header_mode = multiple_files;
1215   int exit_status = 0;
1216   /* If from_start, the number of items to skip before printing; otherwise,
1217      the number of items at the end of the file to print.  Although the type
1218      is signed, the value is never negative.  */
1219   off_t n_units = DEFAULT_N_LINES;
1220   int n_files;
1221   char **file;
1222   struct File_spec *F;
1223   int i;
1224
1225   program_name = argv[0];
1226   setlocale (LC_ALL, "");
1227   bindtextdomain (PACKAGE, LOCALEDIR);
1228   textdomain (PACKAGE);
1229
1230   have_read_stdin = 0;
1231
1232   {
1233     int found_obsolescent;
1234     int fail;
1235     found_obsolescent = parse_obsolescent_option (argc,
1236                                                   (const char *const *) argv,
1237                                                   &n_units, &fail);
1238     if (found_obsolescent)
1239       {
1240         if (fail)
1241           exit (EXIT_FAILURE);
1242         optind = 2;
1243       }
1244     else
1245       {
1246         parse_options (argc, argv, &n_units, &header_mode);
1247       }
1248   }
1249
1250   if (show_version)
1251     {
1252       printf ("tail (%s) %s\n", GNU_PACKAGE, VERSION);
1253       exit (EXIT_SUCCESS);
1254     }
1255
1256   if (show_help)
1257     usage (0);
1258
1259   /* To start printing with item N_UNITS from the start of the file, skip
1260      N_UNITS - 1 items.  `tail +0' is actually meaningless, but for Unix
1261      compatibility it's treated the same as `tail +1'.  */
1262   if (from_start)
1263     {
1264       if (n_units)
1265         --n_units;
1266     }
1267
1268   n_files = argc - optind;
1269   file = argv + optind;
1270
1271   if (n_files == 0)
1272     {
1273       static char *dummy_stdin = "-";
1274       n_files = 1;
1275       file = &dummy_stdin;
1276     }
1277
1278   F = (struct File_spec *) xmalloc (n_files * sizeof (F[0]));
1279   for (i = 0; i < n_files; i++)
1280     F[i].name = file[i];
1281
1282   if (header_mode == always
1283       || (header_mode == multiple_files && n_files > 1))
1284     print_headers = 1;
1285
1286   for (i = 0; i < n_files; i++)
1287     exit_status |= tail_file (&F[i], n_units);
1288
1289   if (forever)
1290     tail_forever (F, n_files);
1291
1292   if (have_read_stdin && close (0) < 0)
1293     error (EXIT_FAILURE, errno, "-");
1294   if (fclose (stdout) == EOF)
1295     error (EXIT_FAILURE, errno, _("write error"));
1296   exit (exit_status == 0 ? EXIT_SUCCESS : EXIT_FAILURE);
1297 }