(file_lines): Fix serious bug introduced with last changes.
[coreutils.git] / src / tail.c
blobef125728d80f88ee151cfbafb65f730b019e3cd3
1 /* tail -- output the last part of file(s)
2 Copyright (C) 89, 90, 91, 1995-1999 Free Software Foundation, Inc.
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.
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.
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. */
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.
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>. */
26 #include <config.h>
28 #include <stdio.h>
29 #include <assert.h>
30 #include <getopt.h>
31 #include <sys/types.h>
33 #include "system.h"
34 #include "argmatch.h"
35 #include "error.h"
36 #include "safe-read.h"
37 #include "xstrtoul.h"
39 /* The official name of this program (e.g., no `g' prefix). */
40 #define PROGRAM_NAME "tail"
42 #define AUTHORS \
43 "Paul Rubin, David MacKenzie, Ian Lance Taylor, and Jim Meyering"
45 #ifndef OFF_T_MIN
46 # define OFF_T_MIN TYPE_MINIMUM (off_t)
47 #endif
49 #ifndef OFF_T_MAX
50 # define OFF_T_MAX TYPE_MAXIMUM (off_t)
51 #endif
53 /* Number of items to tail. */
54 #define DEFAULT_N_LINES 10
56 /* Size of atomic reads. */
57 #ifndef BUFSIZ
58 # define BUFSIZ (512 * 8)
59 #endif
61 /* A special value for dump_remainder's N_BYTES parameter. */
62 #define COPY_TO_EOF OFF_T_MAX
64 /* FIXME: make Follow_name the default? */
65 #define DEFAULT_FOLLOW_MODE Follow_descriptor
67 enum Follow_mode
69 /* Follow the name of each file: if the file is renamed, try to reopen
70 that name and track the end of the new file if/when it's recreated.
71 This is useful for tracking logs that are occasionally rotated. */
72 Follow_name = 1,
74 /* Follow each descriptor obtained upon opening a file.
75 That means we'll continue to follow the end of a file even after
76 it has been renamed or unlinked. */
77 Follow_descriptor = 2,
80 static char const *const follow_mode_string[] =
82 "descriptor", "name", 0
85 static enum Follow_mode const follow_mode_map[] =
87 Follow_descriptor, Follow_name,
90 struct File_spec
92 /* The actual file name, or "-" for stdin. */
93 char *name;
95 /* File descriptor on which the file is open; -1 if it's not open. */
96 int fd;
98 /* The size of the file the last time we checked. */
99 off_t size;
101 /* The device and inode of the file the last time we checked. */
102 dev_t dev;
103 ino_t ino;
105 /* FIXME: describe */
106 unsigned int n_stat_calls;
108 /* FIXME: describe */
109 unsigned int n_unchanged_stats;
111 /* FIXME: describe */
112 unsigned int n_consecutive_size_changes;
114 /* FIXME: describe */
115 int missing;
118 /* FIXME: describe */
119 static int allow_missing;
121 /* If nonzero, interpret the numeric argument as the number of lines.
122 Otherwise, interpret it as the number of bytes. */
123 static int count_lines;
125 /* Whether we follow the name of each file or the file descriptor
126 that is initially associated with each name. */
127 static enum Follow_mode follow_mode = Follow_descriptor;
129 /* If nonzero, read from the ends of all specified files until killed. */
130 static int forever;
132 /* If nonzero, count from start of file instead of end. */
133 static int from_start;
135 /* If nonzero, print filename headers. */
136 static int print_headers;
138 /* When to print the filename banners. */
139 enum header_mode
141 multiple_files, always, never
144 /* When tailing a file by name, if there have been this many consecutive
145 stat calls for which the size has remained the same, then open/fstat
146 the file to determine if that file name is still associated with the
147 same device/inode-number pair as before. This option is meaningful only
148 when following by name. --max-unchanged-stats=N */
149 #define DEFAULT_MAX_N_UNCHANGED_STATS_BETWEEN_OPENS 5
150 static unsigned long max_n_unchanged_stats_between_opens =
151 DEFAULT_MAX_N_UNCHANGED_STATS_BETWEEN_OPENS;
153 /* This variable is used to ensure that a file that is unlinked or moved
154 aside, yet always growing will be recognized as having been renamed.
155 After detecting this many consecutive size changes for a file, open/fstat
156 the file to determine if that file name is still associated with the
157 same device/inode-number pair as before. This option is meaningful only
158 when following by name. --max-n-consecutive-size-changes=N */
159 #define DEFAULT_MAX_N_CONSECUTIVE_SIZE_CHANGES 200
160 static unsigned long max_n_consecutive_size_changes_between_opens =
161 DEFAULT_MAX_N_CONSECUTIVE_SIZE_CHANGES;
163 /* The name this program was run with. */
164 char *program_name;
166 /* The number of seconds to sleep between accesses. */
167 static unsigned int sleep_interval = 1;
169 /* Nonzero if we have ever read standard input. */
170 static int have_read_stdin;
172 static struct option const long_options[] =
174 {"allow-missing", no_argument, NULL, CHAR_MAX + 1},
175 {"bytes", required_argument, NULL, 'c'},
176 {"follow", optional_argument, NULL, 'f'},
177 {"lines", required_argument, NULL, 'n'},
178 {"max-unchanged-stats", required_argument, NULL, CHAR_MAX + 2},
179 {"max-consecutive-size-changes", required_argument, NULL, CHAR_MAX + 3},
180 {"quiet", no_argument, NULL, 'q'},
181 {"silent", no_argument, NULL, 'q'},
182 {"sleep-interval", required_argument, NULL, 's'},
183 {"verbose", no_argument, NULL, 'v'},
184 {GETOPT_HELP_OPTION_DECL},
185 {GETOPT_VERSION_OPTION_DECL},
186 {NULL, 0, NULL, 0}
189 void
190 usage (int status)
192 if (status != 0)
193 fprintf (stderr, _("Try `%s --help' for more information.\n"),
194 program_name);
195 else
197 printf (_("\
198 Usage: %s [OPTION]... [FILE]...\n\
200 program_name);
201 printf (_("\
202 Print last 10 lines of each FILE to standard output.\n\
203 With more than one FILE, precede each with a header giving the file name.\n\
204 With no FILE, or when FILE is -, read standard input.\n\
206 --allow-missing FIXME\n\
207 -c, --bytes=N output the last N bytes\n\
208 -f, --follow[={name|descriptor}] output appended data as the file grows\n\
209 -n, --lines=N output the last N lines, instead of last 10\n\
210 --max-unchanged-stats=N FIXME describe and mention default\n\
211 --max-consecutive-size-changes=N FIXME describe and mention default\n\
212 -q, --quiet, --silent never output headers giving file names\n\
213 -s, --sleep-interval=S with -f, sleep S seconds between iterations\n\
214 -v, --verbose always output headers giving file names\n\
215 --help display this help and exit\n\
216 --version output version information and exit\n\
218 If the first character of N (the number of bytes or lines) is a `+',\n\
219 print beginning with the Nth item from the start of each file, otherwise,\n\
220 print the last N items in the file. N may have a multiplier suffix:\n\
221 b for 512, k for 1024, m for 1048576 (1 Meg). A first OPTION of -VALUE\n\
222 or +VALUE is treated like -n VALUE or -n +VALUE unless VALUE has one of\n\
223 the [bkm] suffix multipliers, in which case it is treated like -c VALUE\n\
224 or -c +VALUE.\n\
225 FIXME: describe name vs descriptor\n\
226 "));
227 puts (_("\nReport bugs to <bug-textutils@gnu.org>."));
229 exit (status == 0 ? EXIT_SUCCESS : EXIT_FAILURE);
232 static char *
233 pretty_name (struct File_spec const *f)
235 return (STREQ (f->name, "-") ? "standard input" : f->name);
238 static void
239 xwrite (int fd, char *const buffer, size_t n_bytes)
241 assert (fd == STDOUT_FILENO);
242 assert (n_bytes >= 0);
243 if (n_bytes > 0 && fwrite (buffer, 1, n_bytes, stdout) == 0)
244 error (EXIT_FAILURE, errno, _("write error"));
247 static void
248 close_fd (int fd, const char *filename)
250 if (fd != -1 && fd != STDIN_FILENO && close (fd))
252 error (0, errno, _("closing %s (fd=%d)"), filename, fd);
256 static void
257 write_header (const char *pretty_filename, const char *comment)
259 static int first_file = 1;
261 printf ("%s==> %s%s%s <==\n", (first_file ? "" : "\n"), pretty_filename,
262 (comment ? ": " : ""),
263 (comment ? comment : ""));
264 first_file = 0;
267 /* Read and output N_BYTES of file PRETTY_FILENAME starting at the current
268 position in FD. If N_BYTES is COPY_TO_EOF, then copy until end of file.
269 Return the number of bytes read from the file. */
271 static long
272 dump_remainder (const char *pretty_filename, int fd, off_t n_bytes)
274 char buffer[BUFSIZ];
275 int bytes_read;
276 long n_written;
277 off_t n_remaining = n_bytes;
279 n_written = 0;
280 while (1)
282 long n = MIN (n_remaining, (off_t) BUFSIZ);
283 bytes_read = safe_read (fd, buffer, n);
284 if (bytes_read <= 0)
285 break;
286 xwrite (STDOUT_FILENO, buffer, bytes_read);
287 n_remaining -= bytes_read;
288 n_written += bytes_read;
290 if (bytes_read == -1)
291 error (EXIT_FAILURE, errno, "%s", pretty_filename);
293 return n_written;
296 /* Print the last N_LINES lines from the end of file FD.
297 Go backward through the file, reading `BUFSIZ' bytes at a time (except
298 probably the first), until we hit the start of the file or have
299 read NUMBER newlines.
300 FILE_LENGTH is the length of the file (one more than the offset of the
301 last byte of the file).
302 Return 0 if successful, 1 if an error occurred. */
304 static int
305 file_lines (const char *pretty_filename, int fd, long int n_lines,
306 off_t file_length)
308 char buffer[BUFSIZ];
309 int bytes_read;
310 int i; /* Index into `buffer' for scanning. */
311 off_t pos = file_length;
313 if (n_lines == 0)
314 return 0;
316 /* Set `bytes_read' to the size of the last, probably partial, buffer;
317 0 < `bytes_read' <= `BUFSIZ'. */
318 bytes_read = pos % BUFSIZ;
319 if (bytes_read == 0)
320 bytes_read = BUFSIZ;
321 /* Make `pos' a multiple of `BUFSIZ' (0 if the file is short), so that all
322 reads will be on block boundaries, which might increase efficiency. */
323 pos -= bytes_read;
324 /* FIXME: check lseek return value */
325 lseek (fd, pos, SEEK_SET);
326 bytes_read = safe_read (fd, buffer, bytes_read);
327 if (bytes_read == -1)
329 error (0, errno, "%s", pretty_filename);
330 return 1;
333 /* Count the incomplete line on files that don't end with a newline. */
334 if (bytes_read && buffer[bytes_read - 1] != '\n')
335 --n_lines;
339 /* Scan backward, counting the newlines in this bufferfull. */
340 for (i = bytes_read - 1; i >= 0; i--)
342 /* Have we counted the requested number of newlines yet? */
343 if (buffer[i] == '\n' && n_lines-- == 0)
345 /* If this newline wasn't the last character in the buffer,
346 print the text after it. */
347 if (i != bytes_read - 1)
348 xwrite (STDOUT_FILENO, &buffer[i + 1], bytes_read - (i + 1));
349 dump_remainder (pretty_filename, fd,
350 file_length - (pos + bytes_read));
351 return 0;
354 /* Not enough newlines in that bufferfull. */
355 if (pos == 0)
357 /* Not enough lines in the file; print the entire file. */
358 /* FIXME: check lseek return value */
359 lseek (fd, (off_t) 0, SEEK_SET);
360 dump_remainder (pretty_filename, fd, file_length);
361 return 0;
363 pos -= BUFSIZ;
364 /* FIXME: check lseek return value */
365 lseek (fd, pos, SEEK_SET);
367 while ((bytes_read = safe_read (fd, buffer, BUFSIZ)) > 0);
369 if (bytes_read == -1)
371 error (0, errno, "%s", pretty_filename);
372 return 1;
375 return 0;
378 /* Print the last N_LINES lines from the end of the standard input,
379 open for reading as pipe FD.
380 Buffer the text as a linked list of LBUFFERs, adding them as needed.
381 Return 0 if successful, 1 if an error occured. */
383 static int
384 pipe_lines (const char *pretty_filename, int fd, long int n_lines)
386 struct linebuffer
388 int nbytes, nlines;
389 char buffer[BUFSIZ];
390 struct linebuffer *next;
392 typedef struct linebuffer LBUFFER;
393 LBUFFER *first, *last, *tmp;
394 int i; /* Index into buffers. */
395 int total_lines = 0; /* Total number of newlines in all buffers. */
396 int errors = 0;
398 first = last = (LBUFFER *) xmalloc (sizeof (LBUFFER));
399 first->nbytes = first->nlines = 0;
400 first->next = NULL;
401 tmp = (LBUFFER *) xmalloc (sizeof (LBUFFER));
403 /* Input is always read into a fresh buffer. */
404 while ((tmp->nbytes = safe_read (fd, tmp->buffer, BUFSIZ)) > 0)
406 tmp->nlines = 0;
407 tmp->next = NULL;
409 /* Count the number of newlines just read. */
410 for (i = 0; i < tmp->nbytes; i++)
411 if (tmp->buffer[i] == '\n')
412 ++tmp->nlines;
413 total_lines += tmp->nlines;
415 /* If there is enough room in the last buffer read, just append the new
416 one to it. This is because when reading from a pipe, `nbytes' can
417 often be very small. */
418 if (tmp->nbytes + last->nbytes < BUFSIZ)
420 memcpy (&last->buffer[last->nbytes], tmp->buffer, tmp->nbytes);
421 last->nbytes += tmp->nbytes;
422 last->nlines += tmp->nlines;
424 else
426 /* If there's not enough room, link the new buffer onto the end of
427 the list, then either free up the oldest buffer for the next
428 read if that would leave enough lines, or else malloc a new one.
429 Some compaction mechanism is possible but probably not
430 worthwhile. */
431 last = last->next = tmp;
432 if (total_lines - first->nlines > n_lines)
434 tmp = first;
435 total_lines -= first->nlines;
436 first = first->next;
438 else
439 tmp = (LBUFFER *) xmalloc (sizeof (LBUFFER));
442 if (tmp->nbytes == -1)
444 error (0, errno, "%s", pretty_filename);
445 errors = 1;
446 free ((char *) tmp);
447 goto free_lbuffers;
450 free ((char *) tmp);
452 /* This prevents a core dump when the pipe contains no newlines. */
453 if (n_lines == 0)
454 goto free_lbuffers;
456 /* Count the incomplete line on files that don't end with a newline. */
457 if (last->buffer[last->nbytes - 1] != '\n')
459 ++last->nlines;
460 ++total_lines;
463 /* Run through the list, printing lines. First, skip over unneeded
464 buffers. */
465 for (tmp = first; total_lines - tmp->nlines > n_lines; tmp = tmp->next)
466 total_lines -= tmp->nlines;
468 /* Find the correct beginning, then print the rest of the file. */
469 if (total_lines > n_lines)
471 char *cp;
473 /* Skip `total_lines' - `n_lines' newlines. We made sure that
474 `total_lines' - `n_lines' <= `tmp->nlines'. */
475 cp = tmp->buffer;
476 for (i = total_lines - n_lines; i; --i)
477 while (*cp++ != '\n')
478 /* Do nothing. */ ;
479 i = cp - tmp->buffer;
481 else
482 i = 0;
483 xwrite (STDOUT_FILENO, &tmp->buffer[i], tmp->nbytes - i);
485 for (tmp = tmp->next; tmp; tmp = tmp->next)
486 xwrite (STDOUT_FILENO, tmp->buffer, tmp->nbytes);
488 free_lbuffers:
489 while (first)
491 tmp = first->next;
492 free ((char *) first);
493 first = tmp;
495 return errors;
498 /* Print the last N_BYTES characters from the end of pipe FD.
499 This is a stripped down version of pipe_lines.
500 Return 0 if successful, 1 if an error occurred. */
502 static int
503 pipe_bytes (const char *pretty_filename, int fd, off_t n_bytes)
505 struct charbuffer
507 int nbytes;
508 char buffer[BUFSIZ];
509 struct charbuffer *next;
511 typedef struct charbuffer CBUFFER;
512 CBUFFER *first, *last, *tmp;
513 int i; /* Index into buffers. */
514 int total_bytes = 0; /* Total characters in all buffers. */
515 int errors = 0;
517 first = last = (CBUFFER *) xmalloc (sizeof (CBUFFER));
518 first->nbytes = 0;
519 first->next = NULL;
520 tmp = (CBUFFER *) xmalloc (sizeof (CBUFFER));
522 /* Input is always read into a fresh buffer. */
523 while ((tmp->nbytes = safe_read (fd, tmp->buffer, BUFSIZ)) > 0)
525 tmp->next = NULL;
527 total_bytes += tmp->nbytes;
528 /* If there is enough room in the last buffer read, just append the new
529 one to it. This is because when reading from a pipe, `nbytes' can
530 often be very small. */
531 if (tmp->nbytes + last->nbytes < BUFSIZ)
533 memcpy (&last->buffer[last->nbytes], tmp->buffer, tmp->nbytes);
534 last->nbytes += tmp->nbytes;
536 else
538 /* If there's not enough room, link the new buffer onto the end of
539 the list, then either free up the oldest buffer for the next
540 read if that would leave enough characters, or else malloc a new
541 one. Some compaction mechanism is possible but probably not
542 worthwhile. */
543 last = last->next = tmp;
544 if (total_bytes - first->nbytes > n_bytes)
546 tmp = first;
547 total_bytes -= first->nbytes;
548 first = first->next;
550 else
552 tmp = (CBUFFER *) xmalloc (sizeof (CBUFFER));
556 if (tmp->nbytes == -1)
558 error (0, errno, "%s", pretty_filename);
559 errors = 1;
560 free ((char *) tmp);
561 goto free_cbuffers;
564 free ((char *) tmp);
566 /* Run through the list, printing characters. First, skip over unneeded
567 buffers. */
568 for (tmp = first; total_bytes - tmp->nbytes > n_bytes; tmp = tmp->next)
569 total_bytes -= tmp->nbytes;
571 /* Find the correct beginning, then print the rest of the file.
572 We made sure that `total_bytes' - `n_bytes' <= `tmp->nbytes'. */
573 if (total_bytes > n_bytes)
574 i = total_bytes - n_bytes;
575 else
576 i = 0;
577 xwrite (STDOUT_FILENO, &tmp->buffer[i], tmp->nbytes - i);
579 for (tmp = tmp->next; tmp; tmp = tmp->next)
580 xwrite (STDOUT_FILENO, tmp->buffer, tmp->nbytes);
582 free_cbuffers:
583 while (first)
585 tmp = first->next;
586 free ((char *) first);
587 first = tmp;
589 return errors;
592 /* Skip N_BYTES characters from the start of pipe FD, and print
593 any extra characters that were read beyond that.
594 Return 1 on error, 0 if ok. */
596 static int
597 start_bytes (const char *pretty_filename, int fd, off_t n_bytes)
599 char buffer[BUFSIZ];
600 int bytes_read = 0;
602 while (n_bytes > 0 && (bytes_read = safe_read (fd, buffer, BUFSIZ)) > 0)
603 n_bytes -= bytes_read;
604 if (bytes_read == -1)
606 error (0, errno, "%s", pretty_filename);
607 return 1;
609 else if (n_bytes < 0)
610 xwrite (STDOUT_FILENO, &buffer[bytes_read + n_bytes], -n_bytes);
611 return 0;
614 /* Skip N_LINES lines at the start of file or pipe FD, and print
615 any extra characters that were read beyond that.
616 Return 1 on error, 0 if ok. */
618 static int
619 start_lines (const char *pretty_filename, int fd, long int n_lines)
621 char buffer[BUFSIZ];
622 int bytes_read = 0;
623 int bytes_to_skip = 0;
625 while (n_lines && (bytes_read = safe_read (fd, buffer, BUFSIZ)) > 0)
627 bytes_to_skip = 0;
628 while (bytes_to_skip < bytes_read)
629 if (buffer[bytes_to_skip++] == '\n' && --n_lines == 0)
630 break;
632 if (bytes_read == -1)
634 error (0, errno, "%s", pretty_filename);
635 return 1;
637 else if (bytes_to_skip < bytes_read)
639 xwrite (STDOUT_FILENO, &buffer[bytes_to_skip],
640 bytes_read - bytes_to_skip);
642 return 0;
645 /* FIXME: describe */
647 static void
648 recheck (struct File_spec *f)
650 /* open/fstat the file and announce if dev/ino have changed */
651 struct stat new_stats;
652 int fd;
653 int fail = 0;
654 int is_stdin = (STREQ (f->name, "-"));
655 int was_missing = f->missing;
656 int new_file;
658 fd = (is_stdin ? STDIN_FILENO : open (f->name, O_RDONLY));
660 /* If the open fails because the file doesn't exist,
661 then mark the file as missing. */
662 f->missing = (allow_missing && fd == -1 && errno == ENOENT);
664 if (fd == -1 || fstat (fd, &new_stats) < 0)
666 fail = 1;
667 if (f->missing)
669 if (!was_missing)
670 error (0, 0, "`%s' has been removed", pretty_name (f));
671 else
673 /* say nothing... it's still missing */
676 else
678 error (0, errno, "%s", pretty_name (f));
681 else if (!S_ISREG (new_stats.st_mode)
682 && !S_ISFIFO (new_stats.st_mode))
684 fail = 1;
685 error (0, 0,
686 _("`%s' has been replaced with a non-regular file; \
687 cannot follow end of non-regular file"),
688 pretty_name (f));
691 new_file = 0;
692 if (fail)
694 close_fd (fd, pretty_name (f));
695 close_fd (f->fd, pretty_name (f));
696 f->fd = -1;
698 else if (f->ino != new_stats.st_ino || f->dev != new_stats.st_dev)
700 new_file = 1;
701 if (f->fd == -1)
703 error (0, 0,
704 _("`%s' has appeared; following end of new file"),
705 pretty_name (f));
707 else
709 /* Close the old one. */
710 close_fd (f->fd, pretty_name (f));
712 /* File has been replaced (e.g., via log rotation) --
713 tail the new one. */
714 error (0, 0,
715 _("`%s' has been replaced; following end of new file"),
716 pretty_name (f));
719 else if (f->missing)
721 new_file = 1;
722 error (0, 0, _("`%s' has reappeared"), pretty_name (f));
723 f->missing = 0;
725 else
727 close_fd (fd, pretty_name (f));
730 if (new_file)
732 /* Record new file info in f. */
733 f->fd = fd;
734 f->size = 0; /* Start at the beginning of the file... */
735 f->dev = new_stats.st_dev;
736 f->ino = new_stats.st_ino;
737 f->n_unchanged_stats = 0;
738 f->n_consecutive_size_changes = 0;
739 /* FIXME: check lseek return value */
740 lseek (f->fd, f->size, SEEK_SET);
744 /* FIXME: describe */
746 static unsigned int
747 n_live_files (const struct File_spec *f, int n_files)
749 int i;
750 unsigned int n_live = 0;
752 for (i = 0; i < n_files; i++)
754 if (f[i].fd >= 0)
755 ++n_live;
757 return n_live;
760 /* Tail NFILES files forever, or until killed.
761 The pertinent information for each file is stored in an entry of F.
762 Loop over each of them, doing an fstat to see if they have changed size,
763 and an occasional open/fstat to see if any dev/ino pair has changed.
764 If none of them have changed size in one iteration, sleep for a
765 while and try again. Continue until the user interrupts us. */
767 static void
768 tail_forever (struct File_spec *f, int nfiles)
770 int last;
772 last = nfiles - 1;
774 while (1)
776 int i;
777 int any_changed;
779 any_changed = 0;
780 for (i = 0; i < nfiles; i++)
782 struct stat stats;
784 if (f[i].fd < 0)
786 if (f[i].missing)
787 recheck (&f[i]);
788 continue;
791 if (fstat (f[i].fd, &stats) < 0)
793 error (0, errno, "%s", pretty_name (&f[i]));
794 f[i].fd = -1;
795 continue;
798 if (stats.st_size == f[i].size)
800 f[i].n_consecutive_size_changes = 0;
801 if (++f[i].n_unchanged_stats > max_n_unchanged_stats_between_opens
802 && follow_mode == Follow_name)
804 recheck (&f[i]);
805 f[i].n_unchanged_stats = 0;
808 continue;
811 /* Size changed. */
812 ++f[i].n_consecutive_size_changes;
814 /* Ensure that a file that's unlinked or moved aside, yet always
815 growing will be recognized as having been renamed. */
816 if (follow_mode == Follow_name
817 && (f[i].n_consecutive_size_changes
818 > max_n_consecutive_size_changes_between_opens))
820 f[i].n_consecutive_size_changes = 0;
821 recheck (&f[i]);
824 /* This file has changed size. Print out what we can, and
825 then keep looping. */
827 any_changed = 1;
829 /* reset counter */
830 f[i].n_unchanged_stats = 0;
832 if (stats.st_size < f[i].size)
834 write_header (pretty_name (&f[i]), _("file truncated"));
835 last = i;
836 /* FIXME: check lseek return value */
837 lseek (f[i].fd, stats.st_size, SEEK_SET);
838 f[i].size = stats.st_size;
839 continue;
842 if (i != last)
844 if (print_headers)
845 write_header (pretty_name (&f[i]), NULL);
846 last = i;
848 f[i].size += dump_remainder (pretty_name (&f[i]), f[i].fd,
849 COPY_TO_EOF);
852 if (n_live_files (f, nfiles) == 0 && ! allow_missing)
854 error (0, 0, _("no files remaining"));
855 break;
858 /* If none of the files changed size, sleep. */
859 if (!any_changed)
860 sleep (sleep_interval);
864 /* Output the last N_BYTES bytes of file FILENAME open for reading in FD.
865 Return 0 if successful, 1 if an error occurred. */
867 static int
868 tail_bytes (const char *pretty_filename, int fd, off_t n_bytes)
870 struct stat stats;
872 /* We need binary input, since `tail' relies on `lseek' and byte counts,
873 while binary output will preserve the style (Unix/DOS) of text file. */
874 SET_BINARY2 (fd, STDOUT_FILENO);
876 if (fstat (fd, &stats))
878 error (0, errno, "%s", pretty_filename);
879 return 1;
882 if (from_start)
884 if (S_ISREG (stats.st_mode))
886 /* FIXME: check lseek return value */
887 lseek (fd, n_bytes, SEEK_CUR);
889 else if (start_bytes (pretty_filename, fd, n_bytes))
891 return 1;
893 dump_remainder (pretty_filename, fd, COPY_TO_EOF);
895 else
897 if (S_ISREG (stats.st_mode))
899 off_t current_pos, end_pos;
900 size_t bytes_remaining;
902 if ((current_pos = lseek (fd, (off_t) 0, SEEK_CUR)) != -1
903 && (end_pos = lseek (fd, (off_t) 0, SEEK_END)) != -1)
905 off_t diff;
906 /* Be careful here. The current position may actually be
907 beyond the end of the file. */
908 bytes_remaining = (diff = end_pos - current_pos) < 0 ? 0 : diff;
910 else
912 error (0, errno, "%s", pretty_filename);
913 return 1;
916 if (bytes_remaining <= n_bytes)
918 /* From the current position to end of file, there are no
919 more bytes than have been requested. So reposition the
920 file pointer to the incoming current position and print
921 everything after that. */
922 /* FIXME: check lseek return value */
923 lseek (fd, current_pos, SEEK_SET);
925 else
927 /* There are more bytes remaining than were requested.
928 Back up. */
929 /* FIXME: check lseek return value */
930 lseek (fd, -n_bytes, SEEK_END);
932 dump_remainder (pretty_filename, fd, n_bytes);
934 else
935 return pipe_bytes (pretty_filename, fd, n_bytes);
937 return 0;
940 /* Output the last N_LINES lines of file FILENAME open for reading in FD.
941 Return 0 if successful, 1 if an error occurred. */
943 static int
944 tail_lines (const char *pretty_filename, int fd, long int n_lines)
946 struct stat stats;
947 off_t length;
949 /* We need binary input, since `tail' relies on `lseek' and byte counts,
950 while binary output will preserve the style (Unix/DOS) of text file. */
951 SET_BINARY2 (fd, STDOUT_FILENO);
953 if (fstat (fd, &stats))
955 error (0, errno, "%s", pretty_filename);
956 return 1;
959 if (from_start)
961 if (start_lines (pretty_filename, fd, n_lines))
962 return 1;
963 dump_remainder (pretty_filename, fd, COPY_TO_EOF);
965 else
967 /* Use file_lines only if FD refers to a regular file with
968 its file pointer positioned at beginning of file. */
969 /* FIXME: adding the lseek conjunct is a kludge.
970 Once there's a reasonable test suite, fix the true culprit:
971 file_lines. file_lines shouldn't presume that the input
972 file pointer is initially positioned to beginning of file. */
973 if (S_ISREG (stats.st_mode)
974 && lseek (fd, (off_t) 0, SEEK_CUR) == (off_t) 0)
976 length = lseek (fd, (off_t) 0, SEEK_END);
977 if (length != 0 && file_lines (pretty_filename, fd, n_lines, length))
978 return 1;
980 else
981 return pipe_lines (pretty_filename, fd, n_lines);
983 return 0;
986 /* Display the last N_UNITS units of file FILENAME, open for reading
987 in FD.
988 Return 0 if successful, 1 if an error occurred. */
990 static int
991 tail (const char *pretty_filename, int fd, off_t n_units)
993 if (count_lines)
994 return tail_lines (pretty_filename, fd, (long) n_units);
995 else
996 return tail_bytes (pretty_filename, fd, n_units);
999 /* Display the last N_UNITS units of the file described by F.
1000 Return 0 if successful, 1 if an error occurred. */
1002 static int
1003 tail_file (struct File_spec *f, off_t n_units)
1005 int fd, errors;
1006 struct stat stats;
1008 int is_stdin = (STREQ (f->name, "-"));
1010 if (is_stdin)
1012 have_read_stdin = 1;
1013 fd = STDIN_FILENO;
1015 else
1017 fd = open (f->name, O_RDONLY);
1020 f->missing = (allow_missing && fd == -1 && errno == ENOENT);
1022 if (fd == -1)
1024 if (forever)
1025 f->fd = -1;
1026 error (0, errno, "%s", pretty_name (f));
1027 errors = 1;
1029 else
1031 if (print_headers)
1032 write_header (pretty_name (f), NULL);
1033 errors = tail (pretty_name (f), fd, n_units);
1034 if (forever)
1036 /* FIXME: duplicate code */
1037 if (fstat (fd, &stats) < 0)
1039 error (0, errno, "%s", pretty_name (f));
1040 errors = 1;
1042 else if (!S_ISREG (stats.st_mode) && !S_ISFIFO (stats.st_mode))
1044 error (0, 0, _("%s: cannot follow end of non-regular file"),
1045 pretty_name (f));
1046 errors = 1;
1048 if (errors)
1050 close_fd (fd, pretty_name (f));
1051 f->fd = -1;
1053 else
1055 f->fd = fd;
1056 f->size = stats.st_size;
1057 f->dev = stats.st_dev;
1058 f->ino = stats.st_ino;
1059 f->n_unchanged_stats = 0;
1060 f->n_consecutive_size_changes = 0;
1063 else
1065 if (!is_stdin && close (fd))
1067 error (0, errno, "%s", pretty_name (f));
1068 errors = 1;
1073 return errors;
1076 /* If the command line arguments are of the obsolescent form and the
1077 option string is well-formed, set *FAIL to zero, set *N_UNITS, the
1078 globals COUNT_LINES, FOREVER, and FROM_START, and return non-zero.
1079 Otherwise, if the command line arguments appear to be of the
1080 obsolescent form but the option string is malformed, set *FAIL to
1081 non-zero, don't modify any other parameter or global variable, and
1082 return non-zero. Otherwise, return zero and don't modify any parameter
1083 or global variable. */
1085 static int
1086 parse_obsolescent_option (int argc, const char *const *argv,
1087 off_t *n_units, int *fail)
1089 const char *p = argv[1];
1090 const char *n_string = NULL;
1091 const char *n_string_end;
1093 int t_from_start;
1094 int t_count_lines;
1095 int t_forever;
1097 /* With the obsolescent form, there is one option string and
1098 (technically) at most one file argument. But we allow two or more
1099 by default. */
1100 if (argc < 2)
1101 return 0;
1103 /* If P starts with `+', `-N' (where N is a digit), or `-l',
1104 then it is obsolescent. Return zero otherwise. */
1105 if ( ! (p[0] == '+' || (p[0] == '-' && (p[1] == 'l' || ISDIGIT (p[1])))) )
1106 return 0;
1108 if (*p == '+')
1109 t_from_start = 1;
1110 else if (*p == '-')
1111 t_from_start = 0;
1112 else
1113 return 0;
1115 ++p;
1116 if (ISDIGIT (*p))
1118 n_string = p;
1121 ++p;
1123 while (ISDIGIT (*p));
1125 n_string_end = p;
1127 t_count_lines = 1;
1128 if (*p == 'c')
1130 t_count_lines = 0;
1131 ++p;
1133 else if (*p == 'l')
1135 ++p;
1138 t_forever = 0;
1139 if (*p == 'f')
1141 t_forever = 1;
1142 ++p;
1145 if (*p != '\0')
1147 /* If (argv[1] begins with a `+' or if it begins with `-' followed
1148 by a digit), but has an invalid suffix character, give a diagnostic
1149 and indicate to caller that this *is* of the obsolescent form,
1150 but that it's an invalid option. */
1151 if (t_from_start || n_string)
1153 error (0, 0,
1154 _("%c: invalid suffix character in obsolescent option" ), *p);
1155 *fail = 1;
1156 return 1;
1159 /* Otherwise, it might be a valid non-obsolescent option like -n. */
1160 return 0;
1163 *fail = 0;
1164 if (n_string == NULL)
1165 *n_units = DEFAULT_N_LINES;
1166 else
1168 strtol_error s_err;
1169 unsigned long int tmp_ulong;
1170 char *end;
1171 s_err = xstrtoul (n_string, &end, 10, &tmp_ulong, NULL);
1172 if (s_err == LONGINT_OK && tmp_ulong <= OFF_T_MAX)
1173 *n_units = (off_t) tmp_ulong;
1174 else
1176 /* Extract a NUL-terminated string for the error message. */
1177 size_t len = n_string_end - n_string;
1178 char *n_string_tmp = xmalloc (len + 1);
1180 strncpy (n_string_tmp, n_string, len);
1181 n_string_tmp[len] = '\0';
1183 error (0, 0,
1184 _("%s: %s is so large that it is not representable"),
1185 n_string_tmp, (count_lines
1186 ? _("number of lines")
1187 : _("number of bytes")));
1188 free (n_string_tmp);
1189 *fail = 1;
1193 if (!*fail)
1195 if (argc > 3)
1197 int posix_pedantic = (getenv ("POSIXLY_CORRECT") != NULL);
1199 /* When POSIXLY_CORRECT is set, enforce the `at most one
1200 file argument' requirement. */
1201 if (posix_pedantic)
1203 error (0, 0, _("\
1204 too many arguments; When using tail's obsolescent option syntax (%s)\n\
1205 there may be no more than one file argument. Use the equivalent -n or -c\n\
1206 option instead."), argv[1]);
1207 *fail = 1;
1208 return 1;
1211 #if DISABLED /* FIXME: enable or remove this warning. */
1212 error (0, 0, _("\
1213 Warning: it is not portable to use two or more file arguments with\n\
1214 tail's obsolescent option syntax (%s). Use the equivalent -n or -c\n\
1215 option instead."), argv[1]);
1216 #endif
1219 /* Set globals. */
1220 from_start = t_from_start;
1221 count_lines = t_count_lines;
1222 forever = t_forever;
1225 return 1;
1228 static void
1229 parse_options (int argc, char **argv,
1230 off_t *n_units, enum header_mode *header_mode)
1232 int c;
1234 count_lines = 1;
1235 forever = from_start = print_headers = 0;
1237 while ((c = getopt_long (argc, argv, "c:n:f::qs:v", long_options, NULL))
1238 != -1)
1240 switch (c)
1242 case 0:
1243 break;
1245 case 'c':
1246 case 'n':
1247 count_lines = (c == 'n');
1248 if (*optarg == '+')
1249 from_start = 1;
1250 else if (*optarg == '-')
1251 ++optarg;
1254 strtol_error s_err;
1255 unsigned long int tmp_ulong;
1256 s_err = xstrtoul (optarg, NULL, 10, &tmp_ulong, "bkm");
1257 if (s_err == LONGINT_INVALID)
1259 error (EXIT_FAILURE, 0, "%s: %s", optarg,
1260 (c == 'n'
1261 ? _("invalid number of lines")
1262 : _("invalid number of bytes")));
1264 if (s_err != LONGINT_OK || tmp_ulong > OFF_T_MAX)
1266 error (EXIT_FAILURE, 0,
1267 _("%s: %s is so large that it is not representable"),
1268 optarg,
1269 c == 'n' ? _("number of lines") : _("number of bytes"));
1271 *n_units = (off_t) tmp_ulong;
1273 break;
1275 case 'f':
1276 forever = 1;
1277 if (optarg == NULL)
1278 follow_mode = DEFAULT_FOLLOW_MODE;
1279 else
1280 follow_mode = XARGMATCH ("--follow", optarg,
1281 follow_mode_string, follow_mode_map);
1282 break;
1284 case CHAR_MAX + 1:
1285 allow_missing = 1;
1286 break;
1288 case CHAR_MAX + 2:
1289 /* --max-unchanged-stats=N */
1290 if (xstrtoul (optarg, NULL, 10,
1291 &max_n_unchanged_stats_between_opens, "") != LONGINT_OK)
1293 error (EXIT_FAILURE, 0,
1294 _("%s: invalid maximum number of unchanged stats between opens"),
1295 optarg);
1297 break;
1299 case CHAR_MAX + 3:
1300 /* --max-consecutive-size-changes=N */
1301 if (xstrtoul (optarg, NULL, 10,
1302 &max_n_consecutive_size_changes_between_opens, "")
1303 != LONGINT_OK)
1305 error (EXIT_FAILURE, 0,
1306 _("%s: invalid maximum number of consecutive size changes"),
1307 optarg);
1309 break;
1311 case 'q':
1312 *header_mode = never;
1313 break;
1315 case 's':
1317 strtol_error s_err;
1318 unsigned long int tmp_ulong;
1319 s_err = xstrtoul (optarg, NULL, 10, &tmp_ulong, "");
1320 if (s_err != LONGINT_OK || tmp_ulong > UINT_MAX)
1322 error (EXIT_FAILURE, 0,
1323 _("%s: invalid number of seconds"), optarg);
1325 sleep_interval = tmp_ulong;
1327 break;
1329 case 'v':
1330 *header_mode = always;
1331 break;
1333 case_GETOPT_HELP_CHAR;
1335 case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
1337 default:
1338 usage (1);
1344 main (int argc, char **argv)
1346 enum header_mode header_mode = multiple_files;
1347 int exit_status = 0;
1348 /* If from_start, the number of items to skip before printing; otherwise,
1349 the number of items at the end of the file to print. Although the type
1350 is signed, the value is never negative. */
1351 off_t n_units = DEFAULT_N_LINES;
1352 int n_files;
1353 char **file;
1354 struct File_spec *F;
1355 int i;
1357 program_name = argv[0];
1358 setlocale (LC_ALL, "");
1359 bindtextdomain (PACKAGE, LOCALEDIR);
1360 textdomain (PACKAGE);
1362 have_read_stdin = 0;
1365 int found_obsolescent;
1366 int fail;
1367 found_obsolescent = parse_obsolescent_option (argc,
1368 (const char *const *) argv,
1369 &n_units, &fail);
1370 if (found_obsolescent)
1372 if (fail)
1373 exit (EXIT_FAILURE);
1374 optind = 2;
1376 else
1378 parse_options (argc, argv, &n_units, &header_mode);
1382 /* To start printing with item N_UNITS from the start of the file, skip
1383 N_UNITS - 1 items. `tail +0' is actually meaningless, but for Unix
1384 compatibility it's treated the same as `tail +1'. */
1385 if (from_start)
1387 if (n_units)
1388 --n_units;
1391 n_files = argc - optind;
1392 file = argv + optind;
1394 if (n_files == 0)
1396 static char *dummy_stdin = "-";
1397 n_files = 1;
1398 file = &dummy_stdin;
1401 F = (struct File_spec *) xmalloc (n_files * sizeof (F[0]));
1402 for (i = 0; i < n_files; i++)
1403 F[i].name = file[i];
1405 if (header_mode == always
1406 || (header_mode == multiple_files && n_files > 1))
1407 print_headers = 1;
1409 for (i = 0; i < n_files; i++)
1410 exit_status |= tail_file (&F[i], n_units);
1412 if (forever)
1414 SETVBUF (stdout, NULL, _IONBF, 0);
1415 tail_forever (F, n_files);
1418 if (have_read_stdin && close (0) < 0)
1419 error (EXIT_FAILURE, errno, "-");
1420 if (fclose (stdout) == EOF)
1421 error (EXIT_FAILURE, errno, _("write error"));
1422 exit (exit_status == 0 ? EXIT_SUCCESS : EXIT_FAILURE);