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)
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
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>. */
31 #include <sys/types.h>
36 #include "long-options.h"
37 #include "safe-read.h"
40 /* The official name of this program (e.g., no `g' prefix). */
41 #define PROGRAM_NAME "tail"
44 # define OFF_T_MIN TYPE_MINIMUM (off_t)
48 # define OFF_T_MAX TYPE_MAXIMUM (off_t)
51 /* Number of items to tail. */
52 #define DEFAULT_N_LINES 10
54 /* Size of atomic reads. */
56 # define BUFSIZ (512 * 8)
59 /* FIXME: make Follow_name the default? */
60 #define DEFAULT_FOLLOW_MODE Follow_descriptor
64 /* Follow the name of each file: if the file is renamed, try to reopen
65 that name and track the end of the new file if/when it's recreated.
66 This is useful for tracking logs that are occasionally rotated. */
69 /* Follow each descriptor obtained upon opening a file.
70 That means we'll continue to follow the end of a file even after
71 it has been renamed or unlinked. */
72 Follow_descriptor = 2,
75 static char const *const follow_mode_string[] =
77 "descriptor", "name", 0
80 static enum Follow_mode const follow_mode_map[] =
82 Follow_descriptor, Follow_name,
87 /* The actual file name, or "-" for stdin. */
90 /* File descriptor on which the file is open; -1 if it's not open. */
93 /* The size of the file the last time we checked. */
96 /* The device and inode of the file the last time we checked. */
100 /* FIXME: describe */
101 unsigned int n_stat_calls;
103 /* FIXME: describe */
104 unsigned int n_unchanged_stats;
106 /* FIXME: describe */
107 unsigned int n_consecutive_size_changes;
109 /* FIXME: describe */
113 /* FIXME: describe */
114 static int allow_missing;
116 /* If nonzero, interpret the numeric argument as the number of lines.
117 Otherwise, interpret it as the number of bytes. */
118 static int count_lines;
120 /* Whether we follow the name of each file or the file descriptor
121 that is initially associated with each name. */
122 static enum Follow_mode follow_mode = Follow_descriptor;
124 /* If nonzero, read from the ends of all specified files until killed. */
127 /* If nonzero, count from start of file instead of end. */
128 static int from_start;
130 /* If nonzero, print filename headers. */
131 static int print_headers;
133 /* When to print the filename banners. */
136 multiple_files, always, never
139 /* When tailing a file by name, if there have been this many consecutive
140 stat calls for which the size has remained the same, then open/fstat
141 the file to determine if that file name is still associated with the
142 same device/inode-number pair as before. This option is meaningful only
143 when following by name. --max-unchanged-stats=N */
144 #define DEFAULT_MAX_N_UNCHANGED_STATS_BETWEEN_OPENS 5
145 static unsigned long max_n_unchanged_stats_between_opens =
146 DEFAULT_MAX_N_UNCHANGED_STATS_BETWEEN_OPENS;
148 /* This variable is used to ensure that a file that is unlinked or moved
149 aside, yet always growing will be recognized as having been renamed.
150 After detecting this many consecutive size changes for a file, open/fstat
151 the file to determine if that file name is still associated with the
152 same device/inode-number pair as before. This option is meaningful only
153 when following by name. --max-n-consecutive-size-changes=N */
154 #define DEFAULT_MAX_N_CONSECUTIVE_SIZE_CHANGES 200
155 static unsigned long max_n_consecutive_size_changes_between_opens =
156 DEFAULT_MAX_N_CONSECUTIVE_SIZE_CHANGES;
158 /* The name this program was run with. */
161 /* The number of seconds to sleep between accesses. */
162 static unsigned int sleep_interval = 1;
164 /* Nonzero if we have ever read standard input. */
165 static int have_read_stdin;
167 static struct option const long_options[] =
169 {"allow-missing", no_argument, NULL, CHAR_MAX + 1},
170 {"bytes", required_argument, NULL, 'c'},
171 {"follow", optional_argument, NULL, 'f'},
172 {"lines", required_argument, NULL, 'n'},
173 {"max-unchanged-stats", required_argument, NULL, CHAR_MAX + 2},
174 {"max-consecutive-size-changes", required_argument, NULL, CHAR_MAX + 3},
175 {"quiet", no_argument, NULL, 'q'},
176 {"silent", no_argument, NULL, 'q'},
177 {"sleep-interval", required_argument, NULL, 's'},
178 {"verbose", no_argument, NULL, 'v'},
186 fprintf (stderr, _("Try `%s --help' for more information.\n"),
191 Usage: %s [OPTION]... [FILE]...\n\
195 Print last 10 lines of each FILE to standard output.\n\
196 With more than one FILE, precede each with a header giving the file name.\n\
197 With no FILE, or when FILE is -, read standard input.\n\
199 --allow-missing FIXME\n\
200 -c, --bytes=N output the last N bytes\n\
201 -f, --follow[={name|descriptor}] output appended data as the file grows\n\
202 -n, --lines=N output the last N lines, instead of last 10\n\
203 --max-unchanged-stats=N FIXME describe and mention default\n\
204 --max-consecutive-size-changes=N FIXME describe and mention default\n\
205 -q, --quiet, --silent never output headers giving file names\n\
206 -s, --sleep-interval=S with -f, sleep S seconds between iterations\n\
207 -v, --verbose always output headers giving file names\n\
208 --help display this help and exit\n\
209 --version output version information and exit\n\
211 If the first character of N (the number of bytes or lines) is a `+',\n\
212 print beginning with the Nth item from the start of each file, otherwise,\n\
213 print the last N items in the file. N may have a multiplier suffix:\n\
214 b for 512, k for 1024, m for 1048576 (1 Meg). A first OPTION of -VALUE\n\
215 or +VALUE is treated like -n VALUE or -n +VALUE unless VALUE has one of\n\
216 the [bkm] suffix multipliers, in which case it is treated like -c VALUE\n\
218 FIXME: describe name vs descriptor\n\
220 puts (_("\nReport bugs to <bug-textutils@gnu.org>."));
222 exit (status == 0 ? EXIT_SUCCESS : EXIT_FAILURE);
226 pretty_name (struct File_spec const *f)
228 return (STREQ (f->name, "-") ? "standard input" : f->name);
232 xwrite (int fd, char *const buffer, size_t n_bytes)
235 assert (n_bytes >= 0);
236 if (n_bytes > 0 && fwrite (buffer, 1, n_bytes, stdout) == 0)
237 error (EXIT_FAILURE, errno, _("write error"));
241 close_fd (int fd, const char *filename)
243 if (fd != -1 && fd != STDIN_FILENO && close (fd))
245 error (0, errno, _("closing %s (fd=%d)"), filename, fd);
250 write_header (const char *pretty_filename, const char *comment)
252 static int first_file = 1;
254 printf ("%s==> %s%s%s <==\n", (first_file ? "" : "\n"), pretty_filename,
255 (comment ? ": " : ""),
256 (comment ? comment : ""));
260 /* Print the last N_LINES lines from the end of file FD.
261 Go backward through the file, reading `BUFSIZ' bytes at a time (except
262 probably the first), until we hit the start of the file or have
263 read NUMBER newlines.
264 POS starts out as the length of the file (the offset of the last
265 byte of the file + 1).
266 Return 0 if successful, 1 if an error occurred. */
269 file_lines (const char *pretty_filename, int fd, long int n_lines, off_t pos)
273 int i; /* Index into `buffer' for scanning. */
278 /* Set `bytes_read' to the size of the last, probably partial, buffer;
279 0 < `bytes_read' <= `BUFSIZ'. */
280 bytes_read = pos % BUFSIZ;
283 /* Make `pos' a multiple of `BUFSIZ' (0 if the file is short), so that all
284 reads will be on block boundaries, which might increase efficiency. */
286 /* FIXME: check lseek return value */
287 lseek (fd, pos, SEEK_SET);
288 bytes_read = safe_read (fd, buffer, bytes_read);
289 if (bytes_read == -1)
291 error (0, errno, "%s", pretty_filename);
295 /* Count the incomplete line on files that don't end with a newline. */
296 if (bytes_read && buffer[bytes_read - 1] != '\n')
301 /* Scan backward, counting the newlines in this bufferfull. */
302 for (i = bytes_read - 1; i >= 0; i--)
304 /* Have we counted the requested number of newlines yet? */
305 if (buffer[i] == '\n' && n_lines-- == 0)
307 /* If this newline wasn't the last character in the buffer,
308 print the text after it. */
309 if (i != bytes_read - 1)
310 xwrite (STDOUT_FILENO, &buffer[i + 1], bytes_read - (i + 1));
314 /* Not enough newlines in that bufferfull. */
317 /* Not enough lines in the file; print the entire file. */
318 /* FIXME: check lseek return value */
319 lseek (fd, (off_t) 0, SEEK_SET);
323 /* FIXME: check lseek return value */
324 lseek (fd, pos, SEEK_SET);
326 while ((bytes_read = safe_read (fd, buffer, BUFSIZ)) > 0);
327 if (bytes_read == -1)
329 error (0, errno, "%s", pretty_filename);
335 /* Print the last N_LINES lines from the end of the standard input,
336 open for reading as pipe FD.
337 Buffer the text as a linked list of LBUFFERs, adding them as needed.
338 Return 0 if successful, 1 if an error occured. */
341 pipe_lines (const char *pretty_filename, int fd, long int n_lines)
347 struct linebuffer *next;
349 typedef struct linebuffer LBUFFER;
350 LBUFFER *first, *last, *tmp;
351 int i; /* Index into buffers. */
352 int total_lines = 0; /* Total number of newlines in all buffers. */
355 first = last = (LBUFFER *) xmalloc (sizeof (LBUFFER));
356 first->nbytes = first->nlines = 0;
358 tmp = (LBUFFER *) xmalloc (sizeof (LBUFFER));
360 /* Input is always read into a fresh buffer. */
361 while ((tmp->nbytes = safe_read (fd, tmp->buffer, BUFSIZ)) > 0)
366 /* Count the number of newlines just read. */
367 for (i = 0; i < tmp->nbytes; i++)
368 if (tmp->buffer[i] == '\n')
370 total_lines += tmp->nlines;
372 /* If there is enough room in the last buffer read, just append the new
373 one to it. This is because when reading from a pipe, `nbytes' can
374 often be very small. */
375 if (tmp->nbytes + last->nbytes < BUFSIZ)
377 memcpy (&last->buffer[last->nbytes], tmp->buffer, tmp->nbytes);
378 last->nbytes += tmp->nbytes;
379 last->nlines += tmp->nlines;
383 /* If there's not enough room, link the new buffer onto the end of
384 the list, then either free up the oldest buffer for the next
385 read if that would leave enough lines, or else malloc a new one.
386 Some compaction mechanism is possible but probably not
388 last = last->next = tmp;
389 if (total_lines - first->nlines > n_lines)
392 total_lines -= first->nlines;
396 tmp = (LBUFFER *) xmalloc (sizeof (LBUFFER));
399 if (tmp->nbytes == -1)
401 error (0, errno, "%s", pretty_filename);
409 /* This prevents a core dump when the pipe contains no newlines. */
413 /* Count the incomplete line on files that don't end with a newline. */
414 if (last->buffer[last->nbytes - 1] != '\n')
420 /* Run through the list, printing lines. First, skip over unneeded
422 for (tmp = first; total_lines - tmp->nlines > n_lines; tmp = tmp->next)
423 total_lines -= tmp->nlines;
425 /* Find the correct beginning, then print the rest of the file. */
426 if (total_lines > n_lines)
430 /* Skip `total_lines' - `n_lines' newlines. We made sure that
431 `total_lines' - `n_lines' <= `tmp->nlines'. */
433 for (i = total_lines - n_lines; i; --i)
434 while (*cp++ != '\n')
436 i = cp - tmp->buffer;
440 xwrite (STDOUT_FILENO, &tmp->buffer[i], tmp->nbytes - i);
442 for (tmp = tmp->next; tmp; tmp = tmp->next)
443 xwrite (STDOUT_FILENO, tmp->buffer, tmp->nbytes);
449 free ((char *) first);
455 /* Print the last N_BYTES characters from the end of pipe FD.
456 This is a stripped down version of pipe_lines.
457 Return 0 if successful, 1 if an error occurred. */
460 pipe_bytes (const char *pretty_filename, int fd, off_t n_bytes)
466 struct charbuffer *next;
468 typedef struct charbuffer CBUFFER;
469 CBUFFER *first, *last, *tmp;
470 int i; /* Index into buffers. */
471 int total_bytes = 0; /* Total characters in all buffers. */
474 first = last = (CBUFFER *) xmalloc (sizeof (CBUFFER));
477 tmp = (CBUFFER *) xmalloc (sizeof (CBUFFER));
479 /* Input is always read into a fresh buffer. */
480 while ((tmp->nbytes = safe_read (fd, tmp->buffer, BUFSIZ)) > 0)
484 total_bytes += tmp->nbytes;
485 /* If there is enough room in the last buffer read, just append the new
486 one to it. This is because when reading from a pipe, `nbytes' can
487 often be very small. */
488 if (tmp->nbytes + last->nbytes < BUFSIZ)
490 memcpy (&last->buffer[last->nbytes], tmp->buffer, tmp->nbytes);
491 last->nbytes += tmp->nbytes;
495 /* If there's not enough room, link the new buffer onto the end of
496 the list, then either free up the oldest buffer for the next
497 read if that would leave enough characters, or else malloc a new
498 one. Some compaction mechanism is possible but probably not
500 last = last->next = tmp;
501 if (total_bytes - first->nbytes > n_bytes)
504 total_bytes -= first->nbytes;
509 tmp = (CBUFFER *) xmalloc (sizeof (CBUFFER));
513 if (tmp->nbytes == -1)
515 error (0, errno, "%s", pretty_filename);
523 /* Run through the list, printing characters. First, skip over unneeded
525 for (tmp = first; total_bytes - tmp->nbytes > n_bytes; tmp = tmp->next)
526 total_bytes -= tmp->nbytes;
528 /* Find the correct beginning, then print the rest of the file.
529 We made sure that `total_bytes' - `n_bytes' <= `tmp->nbytes'. */
530 if (total_bytes > n_bytes)
531 i = total_bytes - n_bytes;
534 xwrite (STDOUT_FILENO, &tmp->buffer[i], tmp->nbytes - i);
536 for (tmp = tmp->next; tmp; tmp = tmp->next)
537 xwrite (STDOUT_FILENO, tmp->buffer, tmp->nbytes);
543 free ((char *) first);
549 /* Skip N_BYTES characters from the start of pipe FD, and print
550 any extra characters that were read beyond that.
551 Return 1 on error, 0 if ok. */
554 start_bytes (const char *pretty_filename, int fd, off_t n_bytes)
559 while (n_bytes > 0 && (bytes_read = safe_read (fd, buffer, BUFSIZ)) > 0)
560 n_bytes -= bytes_read;
561 if (bytes_read == -1)
563 error (0, errno, "%s", pretty_filename);
566 else if (n_bytes < 0)
567 xwrite (STDOUT_FILENO, &buffer[bytes_read + n_bytes], -n_bytes);
571 /* Skip N_LINES lines at the start of file or pipe FD, and print
572 any extra characters that were read beyond that.
573 Return 1 on error, 0 if ok. */
576 start_lines (const char *pretty_filename, int fd, long int n_lines)
580 int bytes_to_skip = 0;
582 while (n_lines && (bytes_read = safe_read (fd, buffer, BUFSIZ)) > 0)
585 while (bytes_to_skip < bytes_read)
586 if (buffer[bytes_to_skip++] == '\n' && --n_lines == 0)
589 if (bytes_read == -1)
591 error (0, errno, "%s", pretty_filename);
594 else if (bytes_to_skip < bytes_read)
596 xwrite (STDOUT_FILENO, &buffer[bytes_to_skip],
597 bytes_read - bytes_to_skip);
602 /* Display file PRETTY_FILENAME from the current position in FD to the end.
603 Return the number of bytes read from the file. */
606 dump_remainder (const char *pretty_filename, int fd)
613 while ((bytes_read = safe_read (fd, buffer, BUFSIZ)) > 0)
615 xwrite (STDOUT_FILENO, buffer, bytes_read);
618 if (bytes_read == -1)
619 error (EXIT_FAILURE, errno, "%s", pretty_filename);
624 /* FIXME: describe */
627 recheck (struct File_spec *f)
629 /* open/fstat the file and announce if dev/ino have changed */
630 struct stat new_stats;
633 int is_stdin = (STREQ (f->name, "-"));
634 int was_missing = f->missing;
637 fd = (is_stdin ? STDIN_FILENO : open (f->name, O_RDONLY));
639 /* If the open fails because the file doesn't exist,
640 then mark the file as missing. */
641 f->missing = (allow_missing && fd == -1 && errno == ENOENT);
643 if (fd == -1 || fstat (fd, &new_stats) < 0)
649 error (0, 0, "`%s' has been removed", pretty_name (f));
652 /* say nothing... it's still missing */
657 error (0, errno, "%s", pretty_name (f));
660 else if (!S_ISREG (new_stats.st_mode)
661 && !S_ISFIFO (new_stats.st_mode))
665 _("`%s' has been replaced with a non-regular file; \
666 cannot follow end of non-regular file"),
673 close_fd (fd, pretty_name (f));
674 close_fd (f->fd, pretty_name (f));
677 else if (f->ino != new_stats.st_ino || f->dev != new_stats.st_dev)
683 _("`%s' has appeared; following end of new file"),
688 /* Close the old one. */
689 close_fd (f->fd, pretty_name (f));
691 /* File has been replaced (e.g., via log rotation) --
694 _("`%s' has been replaced; following end of new file"),
701 error (0, 0, _("`%s' has reappeared"), pretty_name (f));
706 close_fd (fd, pretty_name (f));
711 /* Record new file info in f. */
713 f->size = 0; /* Start at the beginning of the file... */
714 f->dev = new_stats.st_dev;
715 f->ino = new_stats.st_ino;
716 f->n_unchanged_stats = 0;
717 f->n_consecutive_size_changes = 0;
718 /* FIXME: check lseek return value */
719 lseek (f->fd, f->size, SEEK_SET);
723 /* FIXME: describe */
726 n_live_files (const struct File_spec *f, int n_files)
729 unsigned int n_live = 0;
731 for (i = 0; i < n_files; i++)
739 /* Tail NFILES files forever, or until killed.
740 The pertinent information for each file is stored in an entry of F.
741 Loop over each of them, doing an fstat to see if they have changed size,
742 and an occasional open/fstat to see if any dev/ino pair has changed.
743 If none of them have changed size in one iteration, sleep for a
744 while and try again. Continue until the user interrupts us. */
747 tail_forever (struct File_spec *f, int nfiles)
759 for (i = 0; i < nfiles; i++)
770 if (fstat (f[i].fd, &stats) < 0)
772 error (0, errno, "%s", pretty_name (&f[i]));
777 if (stats.st_size == f[i].size)
779 f[i].n_consecutive_size_changes = 0;
780 if (++f[i].n_unchanged_stats > max_n_unchanged_stats_between_opens
781 && follow_mode == Follow_name)
784 f[i].n_unchanged_stats = 0;
791 ++f[i].n_consecutive_size_changes;
793 /* Ensure that a file that's unlinked or moved aside, yet always
794 growing will be recognized as having been renamed. */
795 if (follow_mode == Follow_name
796 && (f[i].n_consecutive_size_changes
797 > max_n_consecutive_size_changes_between_opens))
799 f[i].n_consecutive_size_changes = 0;
803 /* This file has changed size. Print out what we can, and
804 then keep looping. */
809 f[i].n_unchanged_stats = 0;
811 if (stats.st_size < f[i].size)
813 write_header (pretty_name (&f[i]), _("file truncated"));
815 /* FIXME: check lseek return value */
816 lseek (f[i].fd, stats.st_size, SEEK_SET);
817 f[i].size = stats.st_size;
824 write_header (pretty_name (&f[i]), NULL);
827 f[i].size += dump_remainder (pretty_name (&f[i]), f[i].fd);
830 if (n_live_files (f, nfiles) == 0 && ! allow_missing)
832 error (0, 0, _("no files remaining"));
836 /* If none of the files changed size, sleep. */
838 sleep (sleep_interval);
842 /* Output the last N_BYTES bytes of file FILENAME open for reading in FD.
843 Return 0 if successful, 1 if an error occurred. */
846 tail_bytes (const char *pretty_filename, int fd, off_t n_bytes)
850 /* We need binary input, since `tail' relies on `lseek' and byte counts,
851 while binary output will preserve the style (Unix/DOS) of text file. */
852 SET_BINARY2 (fd, STDOUT_FILENO);
854 /* FIXME: resolve this like in dd.c. */
855 /* Use fstat instead of checking for errno == ESPIPE because
856 lseek doesn't work on some special files but doesn't return an
858 if (fstat (fd, &stats))
860 error (0, errno, "%s", pretty_filename);
866 if (S_ISREG (stats.st_mode))
868 /* FIXME: check lseek return value */
869 lseek (fd, n_bytes, SEEK_CUR);
871 else if (start_bytes (pretty_filename, fd, n_bytes))
875 dump_remainder (pretty_filename, fd);
879 if (S_ISREG (stats.st_mode))
881 off_t current_pos, end_pos;
882 size_t bytes_remaining;
884 if ((current_pos = lseek (fd, (off_t) 0, SEEK_CUR)) != -1
885 && (end_pos = lseek (fd, (off_t) 0, SEEK_END)) != -1)
888 /* Be careful here. The current position may actually be
889 beyond the end of the file. */
890 bytes_remaining = (diff = end_pos - current_pos) < 0 ? 0 : diff;
894 error (0, errno, "%s", pretty_filename);
898 if (bytes_remaining <= n_bytes)
900 /* From the current position to end of file, there are no
901 more bytes than have been requested. So reposition the
902 file pointer to the incoming current position and print
903 everything after that. */
904 /* FIXME: check lseek return value */
905 lseek (fd, current_pos, SEEK_SET);
909 /* There are more bytes remaining than were requested.
911 /* FIXME: check lseek return value */
912 lseek (fd, -n_bytes, SEEK_END);
914 dump_remainder (pretty_filename, fd);
917 return pipe_bytes (pretty_filename, fd, n_bytes);
922 /* Output the last N_LINES lines of file FILENAME open for reading in FD.
923 Return 0 if successful, 1 if an error occurred. */
926 tail_lines (const char *pretty_filename, int fd, long int n_lines)
931 /* We need binary input, since `tail' relies on `lseek' and byte counts,
932 while binary output will preserve the style (Unix/DOS) of text file. */
933 SET_BINARY2 (fd, STDOUT_FILENO);
935 if (fstat (fd, &stats))
937 error (0, errno, "%s", pretty_filename);
943 if (start_lines (pretty_filename, fd, n_lines))
945 dump_remainder (pretty_filename, fd);
949 /* Use file_lines only if FD refers to a regular file with
950 its file pointer positioned at beginning of file. */
951 /* FIXME: adding the lseek conjunct is a kludge.
952 Once there's a reasonable test suite, fix the true culprit:
953 file_lines. file_lines shouldn't presume that the input
954 file pointer is initially positioned to beginning of file. */
955 if (S_ISREG (stats.st_mode)
956 && lseek (fd, (off_t) 0, SEEK_CUR) == (off_t) 0)
958 length = lseek (fd, (off_t) 0, SEEK_END);
959 if (length != 0 && file_lines (pretty_filename, fd, n_lines, length))
961 dump_remainder (pretty_filename, fd);
964 return pipe_lines (pretty_filename, fd, n_lines);
969 /* Display the last N_UNITS units of file FILENAME, open for reading
971 Return 0 if successful, 1 if an error occurred. */
974 tail (const char *pretty_filename, int fd, off_t n_units)
977 return tail_lines (pretty_filename, fd, (long) n_units);
979 return tail_bytes (pretty_filename, fd, n_units);
982 /* Display the last N_UNITS units of the file described by F.
983 Return 0 if successful, 1 if an error occurred. */
986 tail_file (struct File_spec *f, off_t n_units)
991 int is_stdin = (STREQ (f->name, "-"));
1000 fd = open (f->name, O_RDONLY);
1003 f->missing = (allow_missing && fd == -1 && errno == ENOENT);
1009 error (0, errno, "%s", pretty_name (f));
1015 write_header (pretty_name (f), NULL);
1016 errors = tail (pretty_name (f), fd, n_units);
1019 /* FIXME: duplicate code */
1020 if (fstat (fd, &stats) < 0)
1022 error (0, errno, "%s", pretty_name (f));
1025 else if (!S_ISREG (stats.st_mode) && !S_ISFIFO (stats.st_mode))
1027 error (0, 0, _("%s: cannot follow end of non-regular file"),
1033 close_fd (fd, pretty_name (f));
1039 f->size = stats.st_size;
1040 f->dev = stats.st_dev;
1041 f->ino = stats.st_ino;
1042 f->n_unchanged_stats = 0;
1043 f->n_consecutive_size_changes = 0;
1048 if (!is_stdin && close (fd))
1050 error (0, errno, "%s", pretty_name (f));
1059 /* If the command line arguments are of the obsolescent form and the
1060 option string is well-formed, set *FAIL to zero, set *N_UNITS, the
1061 globals COUNT_LINES, FOREVER, and FROM_START, and return non-zero.
1062 Otherwise, if the command line arguments appear to be of the
1063 obsolescent form but the option string is malformed, set *FAIL to
1064 non-zero, don't modify any other parameter or global variable, and
1065 return non-zero. Otherwise, return zero and don't modify any parameter
1066 or global variable. */
1069 parse_obsolescent_option (int argc, const char *const *argv,
1070 off_t *n_units, int *fail)
1072 const char *p = argv[1];
1073 const char *n_string = NULL;
1074 const char *n_string_end;
1080 /* With the obsolescent form, there is one option string and
1081 (technically) at most one file argument. But we allow two or more
1086 /* If P starts with `+', `-N' (where N is a digit), or `-l',
1087 then it is obsolescent. Return zero otherwise. */
1088 if ( ! (p[0] == '+' || (p[0] == '-' && (p[1] == 'l' || ISDIGIT (p[1])))) )
1106 while (ISDIGIT (*p));
1130 /* If (argv[1] begins with a `+' or if it begins with `-' followed
1131 by a digit), but has an invalid suffix character, give a diagnostic
1132 and indicate to caller that this *is* of the obsolescent form,
1133 but that it's an invalid option. */
1134 if (t_from_start || n_string)
1137 _("%c: invalid suffix character in obsolescent option" ), *p);
1142 /* Otherwise, it might be a valid non-obsolescent option like -n. */
1147 if (n_string == NULL)
1148 *n_units = DEFAULT_N_LINES;
1152 unsigned long int tmp_ulong;
1154 s_err = xstrtoul (n_string, &end, 10, &tmp_ulong, NULL);
1155 if (s_err == LONGINT_OK && tmp_ulong <= OFF_T_MAX)
1156 *n_units = (off_t) tmp_ulong;
1159 /* Extract a NUL-terminated string for the error message. */
1160 size_t len = n_string_end - n_string;
1161 char *n_string_tmp = xmalloc (len + 1);
1163 strncpy (n_string_tmp, n_string, len);
1164 n_string_tmp[len] = '\0';
1167 _("%s: %s is so large that it is not representable"),
1168 n_string_tmp, (count_lines
1169 ? _("number of lines")
1170 : _("number of bytes")));
1171 free (n_string_tmp);
1180 int posix_pedantic = (getenv ("POSIXLY_CORRECT") != NULL);
1182 /* When POSIXLY_CORRECT is set, enforce the `at most one
1183 file argument' requirement. */
1187 too many arguments; When using tail's obsolescent option syntax (%s)\n\
1188 there may be no more than one file argument. Use the equivalent -n or -c\n\
1189 option instead."), argv[1]);
1194 #if DISABLED /* FIXME: enable or remove this warning. */
1196 Warning: it is not portable to use two or more file arguments with\n\
1197 tail's obsolescent option syntax (%s). Use the equivalent -n or -c\n\
1198 option instead."), argv[1]);
1203 from_start = t_from_start;
1204 count_lines = t_count_lines;
1205 forever = t_forever;
1212 parse_options (int argc, char **argv,
1213 off_t *n_units, enum header_mode *header_mode)
1218 forever = from_start = print_headers = 0;
1220 while ((c = getopt_long (argc, argv, "c:n:f::qs:v", long_options, NULL))
1230 count_lines = (c == 'n');
1233 else if (*optarg == '-')
1238 unsigned long int tmp_ulong;
1239 s_err = xstrtoul (optarg, NULL, 10, &tmp_ulong, "bkm");
1240 if (s_err == LONGINT_INVALID)
1242 error (EXIT_FAILURE, 0, "%s: %s", optarg,
1244 ? _("invalid number of lines")
1245 : _("invalid number of bytes")));
1247 if (s_err != LONGINT_OK || tmp_ulong > OFF_T_MAX)
1249 error (EXIT_FAILURE, 0,
1250 _("%s: %s is so large that it is not representable"),
1252 c == 'n' ? _("number of lines") : _("number of bytes"));
1254 *n_units = (off_t) tmp_ulong;
1261 follow_mode = DEFAULT_FOLLOW_MODE;
1263 follow_mode = XARGMATCH ("--follow", optarg,
1264 follow_mode_string, follow_mode_map);
1272 /* --max-unchanged-stats=N */
1273 if (xstrtoul (optarg, NULL, 10,
1274 &max_n_unchanged_stats_between_opens, "") != LONGINT_OK)
1276 error (EXIT_FAILURE, 0,
1277 _("%s: invalid maximum number of unchanged stats between opens"),
1283 /* --max-consecutive-size-changes=N */
1284 if (xstrtoul (optarg, NULL, 10,
1285 &max_n_consecutive_size_changes_between_opens, "")
1288 error (EXIT_FAILURE, 0,
1289 _("%s: invalid maximum number of consecutive size changes"),
1295 *header_mode = never;
1301 unsigned long int tmp_ulong;
1302 s_err = xstrtoul (optarg, NULL, 10, &tmp_ulong, "");
1303 if (s_err != LONGINT_OK || tmp_ulong > UINT_MAX)
1305 error (EXIT_FAILURE, 0,
1306 _("%s: invalid number of seconds"), optarg);
1308 sleep_interval = tmp_ulong;
1313 *header_mode = always;
1323 main (int argc, char **argv)
1325 enum header_mode header_mode = multiple_files;
1326 int exit_status = 0;
1327 /* If from_start, the number of items to skip before printing; otherwise,
1328 the number of items at the end of the file to print. Although the type
1329 is signed, the value is never negative. */
1330 off_t n_units = DEFAULT_N_LINES;
1333 struct File_spec *F;
1336 program_name = argv[0];
1337 setlocale (LC_ALL, "");
1338 bindtextdomain (PACKAGE, LOCALEDIR);
1339 textdomain (PACKAGE);
1341 have_read_stdin = 0;
1343 parse_long_options (argc, argv, PROGRAM_NAME, GNU_PACKAGE, VERSION,
1344 "Paul Rubin, David MacKenzie, Ian Lance Taylor, and Jim Meyering",
1348 int found_obsolescent;
1350 found_obsolescent = parse_obsolescent_option (argc,
1351 (const char *const *) argv,
1353 if (found_obsolescent)
1356 exit (EXIT_FAILURE);
1361 parse_options (argc, argv, &n_units, &header_mode);
1365 /* To start printing with item N_UNITS from the start of the file, skip
1366 N_UNITS - 1 items. `tail +0' is actually meaningless, but for Unix
1367 compatibility it's treated the same as `tail +1'. */
1374 n_files = argc - optind;
1375 file = argv + optind;
1379 static char *dummy_stdin = "-";
1381 file = &dummy_stdin;
1384 F = (struct File_spec *) xmalloc (n_files * sizeof (F[0]));
1385 for (i = 0; i < n_files; i++)
1386 F[i].name = file[i];
1388 if (header_mode == always
1389 || (header_mode == multiple_files && n_files > 1))
1392 for (i = 0; i < n_files; i++)
1393 exit_status |= tail_file (&F[i], n_units);
1397 SETVBUF (stdout, NULL, _IONBF, 0);
1398 tail_forever (F, n_files);
1401 if (have_read_stdin && close (0) < 0)
1402 error (EXIT_FAILURE, errno, "-");
1403 if (fclose (stdout) == EOF)
1404 error (EXIT_FAILURE, errno, _("write error"));
1405 exit (exit_status == 0 ? EXIT_SUCCESS : EXIT_FAILURE);