OpenCoverage

tail.c

Absolute File Name:/home/opencoverage/opencoverage/guest-scripts/coreutils/src/src/tail.c
Source codeSwitch to Preprocessed file
LineSourceCount
1/* tail -- output the last part of file(s)-
2 Copyright (C) 1989-2018 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 3 of the License, or-
7 (at your option) 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, see <https://www.gnu.org/licenses/>. */-
16-
17/* Can display any amount of data, unlike the Unix version, which uses-
18 a fixed size buffer and therefore can only deliver a limited number-
19 of lines.-
20-
21 Original version by Paul Rubin <phr@ocf.berkeley.edu>.-
22 Extensions by David MacKenzie <djm@gnu.ai.mit.edu>.-
23 tail -f for multiple files by Ian Lance Taylor <ian@airs.com>.-
24 inotify back-end by Giuseppe Scrivano <gscrivano@gnu.org>. */-
25-
26#include <config.h>-
27-
28#include <stdio.h>-
29#include <assert.h>-
30#include <getopt.h>-
31#include <sys/types.h>-
32#include <signal.h>-
33-
34#include "system.h"-
35#include "argmatch.h"-
36#include "c-strtod.h"-
37#include "die.h"-
38#include "error.h"-
39#include "fcntl--.h"-
40#include "isapipe.h"-
41#include "posixver.h"-
42#include "quote.h"-
43#include "safe-read.h"-
44#include "stat-size.h"-
45#include "stat-time.h"-
46#include "xbinary-io.h"-
47#include "xdectoint.h"-
48#include "xnanosleep.h"-
49#include "xstrtol.h"-
50#include "xstrtod.h"-
51-
52#if HAVE_INOTIFY-
53# include "hash.h"-
54# include <sys/inotify.h>-
55/* 'select' is used by tail_forever_inotify. */-
56# include <sys/select.h>-
57-
58/* inotify needs to know if a file is local. */-
59# include "fs.h"-
60# include "fs-is-local.h"-
61# if HAVE_SYS_STATFS_H-
62# include <sys/statfs.h>-
63# elif HAVE_SYS_VFS_H-
64# include <sys/vfs.h>-
65# endif-
66#endif-
67-
68/* The official name of this program (e.g., no 'g' prefix). */-
69#define PROGRAM_NAME "tail"-
70-
71#define AUTHORS \-
72 proper_name ("Paul Rubin"), \-
73 proper_name ("David MacKenzie"), \-
74 proper_name ("Ian Lance Taylor"), \-
75 proper_name ("Jim Meyering")-
76-
77/* Number of items to tail. */-
78#define DEFAULT_N_LINES 10-
79-
80/* Special values for dump_remainder's N_BYTES parameter. */-
81#define COPY_TO_EOF UINTMAX_MAX-
82#define COPY_A_BUFFER (UINTMAX_MAX - 1)-
83-
84/* FIXME: make Follow_name the default? */-
85#define DEFAULT_FOLLOW_MODE Follow_descriptor-
86-
87enum Follow_mode-
88{-
89 /* Follow the name of each file: if the file is renamed, try to reopen-
90 that name and track the end of the new file if/when it's recreated.-
91 This is useful for tracking logs that are occasionally rotated. */-
92 Follow_name = 1,-
93-
94 /* Follow each descriptor obtained upon opening a file.-
95 That means we'll continue to follow the end of a file even after-
96 it has been renamed or unlinked. */-
97 Follow_descriptor = 2-
98};-
99-
100/* The types of files for which tail works. */-
101#define IS_TAILABLE_FILE_TYPE(Mode) \-
102 (S_ISREG (Mode) || S_ISFIFO (Mode) || S_ISSOCK (Mode) || S_ISCHR (Mode))-
103-
104static char const *const follow_mode_string[] =-
105{-
106 "descriptor", "name", NULL-
107};-
108-
109static enum Follow_mode const follow_mode_map[] =-
110{-
111 Follow_descriptor, Follow_name,-
112};-
113-
114struct File_spec-
115{-
116 /* The actual file name, or "-" for stdin. */-
117 char *name;-
118-
119 /* Attributes of the file the last time we checked. */-
120 off_t size;-
121 struct timespec mtime;-
122 dev_t dev;-
123 ino_t ino;-
124 mode_t mode;-
125-
126 /* The specified name initially referred to a directory or some other-
127 type for which tail isn't meaningful. Unlike for a permission problem-
128 (tailable, below) once this is set, the name is not checked ever again. */-
129 bool ignore;-
130-
131 /* See the description of fremote. */-
132 bool remote;-
133-
134 /* A file is tailable if it exists, is readable, and is of type-
135 IS_TAILABLE_FILE_TYPE. */-
136 bool tailable;-
137-
138 /* File descriptor on which the file is open; -1 if it's not open. */-
139 int fd;-
140-
141 /* The value of errno seen last time we checked this file. */-
142 int errnum;-
143-
144 /* 1 if O_NONBLOCK is clear, 0 if set, -1 if not known. */-
145 int blocking;-
146-
147#if HAVE_INOTIFY-
148 /* The watch descriptor used by inotify. */-
149 int wd;-
150-
151 /* The parent directory watch descriptor. It is used only-
152 * when Follow_name is used. */-
153 int parent_wd;-
154-
155 /* Offset in NAME of the basename part. */-
156 size_t basename_start;-
157#endif-
158-
159 /* See description of DEFAULT_MAX_N_... below. */-
160 uintmax_t n_unchanged_stats;-
161};-
162-
163/* Keep trying to open a file even if it is inaccessible when tail starts-
164 or if it becomes inaccessible later -- useful only with -f. */-
165static bool reopen_inaccessible_files;-
166-
167/* If true, interpret the numeric argument as the number of lines.-
168 Otherwise, interpret it as the number of bytes. */-
169static bool count_lines;-
170-
171/* Whether we follow the name of each file or the file descriptor-
172 that is initially associated with each name. */-
173static enum Follow_mode follow_mode = Follow_descriptor;-
174-
175/* If true, read from the ends of all specified files until killed. */-
176static bool forever;-
177-
178/* If true, monitor output so we exit if pipe reader terminates. */-
179static bool monitor_output;-
180-
181/* If true, count from start of file instead of end. */-
182static bool from_start;-
183-
184/* If true, print filename headers. */-
185static bool print_headers;-
186-
187/* Character to split lines by. */-
188static char line_end;-
189-
190/* When to print the filename banners. */-
191enum header_mode-
192{-
193 multiple_files, always, never-
194};-
195-
196/* When tailing a file by name, if there have been this many consecutive-
197 iterations for which the file has not changed, then open/fstat-
198 the file to determine if that file name is still associated with the-
199 same device/inode-number pair as before. This option is meaningful only-
200 when following by name. --max-unchanged-stats=N */-
201#define DEFAULT_MAX_N_UNCHANGED_STATS_BETWEEN_OPENS 5-
202static uintmax_t max_n_unchanged_stats_between_opens =-
203 DEFAULT_MAX_N_UNCHANGED_STATS_BETWEEN_OPENS;-
204-
205/* The process ID of the process (presumably on the current host)-
206 that is writing to all followed files. */-
207static pid_t pid;-
208-
209/* True if we have ever read standard input. */-
210static bool have_read_stdin;-
211-
212/* If nonzero, skip the is-regular-file test used to determine whether-
213 to use the lseek optimization. Instead, use the more general (and-
214 more expensive) code unconditionally. Intended solely for testing. */-
215static bool presume_input_pipe;-
216-
217/* If nonzero then don't use inotify even if available. */-
218static bool disable_inotify;-
219-
220/* For long options that have no equivalent short option, use a-
221 non-character as a pseudo short option, starting with CHAR_MAX + 1. */-
222enum-
223{-
224 RETRY_OPTION = CHAR_MAX + 1,-
225 MAX_UNCHANGED_STATS_OPTION,-
226 PID_OPTION,-
227 PRESUME_INPUT_PIPE_OPTION,-
228 LONG_FOLLOW_OPTION,-
229 DISABLE_INOTIFY_OPTION-
230};-
231-
232static struct option const long_options[] =-
233{-
234 {"bytes", required_argument, NULL, 'c'},-
235 {"follow", optional_argument, NULL, LONG_FOLLOW_OPTION},-
236 {"lines", required_argument, NULL, 'n'},-
237 {"max-unchanged-stats", required_argument, NULL, MAX_UNCHANGED_STATS_OPTION},-
238 {"-disable-inotify", no_argument, NULL,-
239 DISABLE_INOTIFY_OPTION}, /* do not document */-
240 {"pid", required_argument, NULL, PID_OPTION},-
241 {"-presume-input-pipe", no_argument, NULL,-
242 PRESUME_INPUT_PIPE_OPTION}, /* do not document */-
243 {"quiet", no_argument, NULL, 'q'},-
244 {"retry", no_argument, NULL, RETRY_OPTION},-
245 {"silent", no_argument, NULL, 'q'},-
246 {"sleep-interval", required_argument, NULL, 's'},-
247 {"verbose", no_argument, NULL, 'v'},-
248 {"zero-terminated", no_argument, NULL, 'z'},-
249 {GETOPT_HELP_OPTION_DECL},-
250 {GETOPT_VERSION_OPTION_DECL},-
251 {NULL, 0, NULL, 0}-
252};-
253-
254void-
255usage (int status)-
256{-
257 if (status != EXIT_SUCCESS)
status != 0Description
TRUEevaluated 3 times by 1 test
Evaluated by:
  • tail
FALSEevaluated 14 times by 1 test
Evaluated by:
  • tail
3-14
258 emit_try_help ();
executed 3 times by 1 test: end of block
Executed by:
  • tail
3
259 else-
260 {-
261 printf (_("\-
262Usage: %s [OPTION]... [FILE]...\n\-
263"),-
264 program_name);-
265 printf (_("\-
266Print the last %d lines of each FILE to standard output.\n\-
267With more than one FILE, precede each with a header giving the file name.\n\-
268"), DEFAULT_N_LINES);-
269-
270 emit_stdin_note ();-
271 emit_mandatory_arg_note ();-
272-
273 fputs (_("\-
274 -c, --bytes=[+]NUM output the last NUM bytes; or use -c +NUM to\n\-
275 output starting with byte NUM of each file\n\-
276"), stdout);-
277 fputs (_("\-
278 -f, --follow[={name|descriptor}]\n\-
279 output appended data as the file grows;\n\-
280 an absent option argument means 'descriptor'\n\-
281 -F same as --follow=name --retry\n\-
282"), stdout);-
283 printf (_("\-
284 -n, --lines=[+]NUM output the last NUM lines, instead of the last %d;\n\-
285 or use -n +NUM to output starting with line NUM\n\-
286 --max-unchanged-stats=N\n\-
287 with --follow=name, reopen a FILE which has not\n\-
288 changed size after N (default %d) iterations\n\-
289 to see if it has been unlinked or renamed\n\-
290 (this is the usual case of rotated log files);\n\-
291 with inotify, this option is rarely useful\n\-
292"),-
293 DEFAULT_N_LINES,-
294 DEFAULT_MAX_N_UNCHANGED_STATS_BETWEEN_OPENS-
295 );-
296 fputs (_("\-
297 --pid=PID with -f, terminate after process ID, PID dies\n\-
298 -q, --quiet, --silent never output headers giving file names\n\-
299 --retry keep trying to open a file if it is inaccessible\n\-
300"), stdout);-
301 fputs (_("\-
302 -s, --sleep-interval=N with -f, sleep for approximately N seconds\n\-
303 (default 1.0) between iterations;\n\-
304 with inotify and --pid=P, check process P at\n\-
305 least once every N seconds\n\-
306 -v, --verbose always output headers giving file names\n\-
307"), stdout);-
308 fputs (_("\-
309 -z, --zero-terminated line delimiter is NUL, not newline\n\-
310"), stdout);-
311 fputs (HELP_OPTION_DESCRIPTION, stdout);-
312 fputs (VERSION_OPTION_DESCRIPTION, stdout);-
313 fputs (_("\-
314\n\-
315NUM may have a multiplier suffix:\n\-
316b 512, kB 1000, K 1024, MB 1000*1000, M 1024*1024,\n\-
317GB 1000*1000*1000, G 1024*1024*1024, and so on for T, P, E, Z, Y.\n\-
318\n\-
319"), stdout);-
320 fputs (_("\-
321With --follow (-f), tail defaults to following the file descriptor, which\n\-
322means that even if a tail'ed file is renamed, tail will continue to track\n\-
323its end. This default behavior is not desirable when you really want to\n\-
324track the actual name of the file, not the file descriptor (e.g., log\n\-
325rotation). Use --follow=name in that case. That causes tail to track the\n\-
326named file in a way that accommodates renaming, removal and creation.\n\-
327"), stdout);-
328 emit_ancillary_info (PROGRAM_NAME);-
329 }
executed 14 times by 1 test: end of block
Executed by:
  • tail
14
330 exit (status);
executed 17 times by 1 test: exit (status);
Executed by:
  • tail
17
331}-
332-
333/* If the output has gone away, then terminate-
334 as we would if we had written to this output. */-
335static void-
336check_output_alive (void)-
337{-
338 if (! monitor_output)
! monitor_outputDescription
TRUEevaluated 189 times by 1 test
Evaluated by:
  • tail
FALSEevaluated 100 times by 1 test
Evaluated by:
  • tail
100-189
339 return;
executed 189 times by 1 test: return;
Executed by:
  • tail
189
340-
341 struct timeval delay;-
342 delay.tv_sec = delay.tv_usec = 0;-
343-
344 fd_set rfd;-
345 FD_ZERO (&rfd);-
346 FD_SET (STDOUT_FILENO, &rfd);-
347-
348 /* readable event on STDOUT is equivalent to POLLERR,-
349 and implies an error condition on output like broken pipe. */-
350 if (select (STDOUT_FILENO + 1, &rfd, NULL, NULL, &delay) == 1)
select ( 1 + 1..., &delay) == 1Description
TRUEevaluated 99 times by 1 test
Evaluated by:
  • tail
FALSEevaluated 1 time by 1 test
Evaluated by:
  • tail
1-99
351 raise (SIGPIPE);
executed 99 times by 1 test: raise ( 13 );
Executed by:
  • tail
99
352}
executed 100 times by 1 test: end of block
Executed by:
  • tail
100
353-
354static bool-
355valid_file_spec (struct File_spec const *f)-
356{-
357 /* Exactly one of the following subexpressions must be true. */-
358 return ((f->fd == -1) ^ (f->errnum == 0));
executed 1113 times by 1 test: return ((f->fd == -1) ^ (f->errnum == 0));
Executed by:
  • tail
1113
359}-
360-
361static char const *-
362pretty_name (struct File_spec const *f)-
363{-
364 return (STREQ (f->name, "-") ? _("standard input") : f->name);
executed 3932 times by 1 test: return (( __extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p ( f->name ) && __builtin_constant_p ( "-" ) && (__s1_len = __builtin_strlen ( f->name ), __s2_len = __builtin_strlen ( "-" ), (!((size_t)(const void *)(( f->name ) + 1) - (size_t)...[2] - __s2[2]); if (__s2_len > 2 && __result == 0) __result = (((const unsigned char *) (const char *) ( "-" ))[3] - __s2[3]); } } __result; }))) : __builtin_strcmp ( f->name , "-" )))); }) == 0) ? dcgettext (((void *)0), "standard input" , 5) : f->name);
Executed by:
  • tail
never executed: __result = (((const unsigned char *) (const char *) ( f->name ))[3] - __s2[3]);
never executed: end of block
never executed: end of block
never executed: __result = (((const unsigned char *) (const char *) ( "-" ))[3] - __s2[3]);
never executed: end of block
executed 95 times by 1 test: end of block
Executed by:
  • tail
__s1_len > 0Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s1_len > 1Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s1_len > 2Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s2_len > 0Description
TRUEevaluated 3932 times by 1 test
Evaluated by:
  • tail
FALSEnever evaluated
__result == 0Description
TRUEevaluated 95 times by 1 test
Evaluated by:
  • tail
FALSEevaluated 3837 times by 1 test
Evaluated by:
  • tail
__s2_len > 1Description
TRUEnever evaluated
FALSEevaluated 95 times by 1 test
Evaluated by:
  • tail
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s2_len > 2Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
0-3932
365}-
366-
367/* Record a file F with descriptor FD, size SIZE, status ST, and-
368 blocking status BLOCKING. */-
369-
370static void-
371record_open_fd (struct File_spec *f, int fd,-
372 off_t size, struct stat const *st,-
373 int blocking)-
374{-
375 f->fd = fd;-
376 f->size = size;-
377 f->mtime = get_stat_mtime (st);-
378 f->dev = st->st_dev;-
379 f->ino = st->st_ino;-
380 f->mode = st->st_mode;-
381 f->blocking = blocking;-
382 f->n_unchanged_stats = 0;-
383 f->ignore = false;-
384}
executed 411 times by 1 test: end of block
Executed by:
  • tail
411
385-
386/* Close the file with descriptor FD and name FILENAME. */-
387-
388static void-
389close_fd (int fd, const char *filename)-
390{-
391 if (fd != -1 && fd != STDIN_FILENO && close (fd))
fd != -1Description
TRUEevaluated 835 times by 1 test
Evaluated by:
  • tail
FALSEevaluated 324 times by 1 test
Evaluated by:
  • tail
fd != 0Description
TRUEevaluated 834 times by 1 test
Evaluated by:
  • tail
FALSEevaluated 1 time by 1 test
Evaluated by:
  • tail
close (fd)Description
TRUEnever evaluated
FALSEevaluated 834 times by 1 test
Evaluated by:
  • tail
0-835
392 {-
393 error (0, errno, _("closing %s (fd=%d)"), quoteaf (filename), fd);-
394 }
never executed: end of block
0
395}
executed 1159 times by 1 test: end of block
Executed by:
  • tail
1159
396-
397static void-
398write_header (const char *pretty_filename)-
399{-
400 static bool first_file = true;-
401-
402 printf ("%s==> %s <==\n", (first_file ? "" : "\n"), pretty_filename);-
403 first_file = false;-
404}
executed 28 times by 1 test: end of block
Executed by:
  • tail
28
405-
406/* Write N_BYTES from BUFFER to stdout.-
407 Exit immediately on error with a single diagnostic. */-
408-
409static void-
410xwrite_stdout (char const *buffer, size_t n_bytes)-
411{-
412 if (n_bytes > 0 && fwrite (buffer, 1, n_bytes, stdout) < n_bytes)
never executed: break;
(__builtin_exp...r++))) == (-1)Description
TRUEnever evaluated
FALSEnever evaluated
__cnt > 0Description
TRUEnever evaluated
FALSEnever evaluated
__builtin_expe...write_end), 0)Description
TRUEnever evaluated
FALSEnever evaluated
n_bytes > 0Description
TRUEevaluated 276 times by 1 test
Evaluated by:
  • tail
FALSEevaluated 4 times by 1 test
Evaluated by:
  • tail
(__extension__...)))) < n_bytesDescription
TRUEnever evaluated
FALSEevaluated 276 times by 1 test
Evaluated by:
  • tail
__builtin_constant_p ( 1 )Description
TRUEevaluated 276 times by 1 test
Evaluated by:
  • tail
FALSEnever evaluated
__builtin_cons..._p ( n_bytes )Description
TRUEnever evaluated
FALSEevaluated 276 times by 1 test
Evaluated by:
  • tail
(size_t) ( 1 )...n_bytes ) <= 8Description
TRUEnever evaluated
FALSEnever evaluated
(size_t) ( 1 ) != 0Description
TRUEnever evaluated
FALSEnever evaluated
__builtin_constant_p ( 1 )Description
TRUEevaluated 276 times by 1 test
Evaluated by:
  • tail
FALSEnever evaluated
(size_t) ( 1 ) == 0Description
TRUEnever evaluated
FALSEevaluated 276 times by 1 test
Evaluated by:
  • tail
__builtin_cons..._p ( n_bytes )Description
TRUEnever evaluated
FALSEevaluated 276 times by 1 test
Evaluated by:
  • tail
(size_t) ( n_bytes ) == 0Description
TRUEnever evaluated
FALSEnever evaluated
0-276
413 {-
414 clearerr (stdout); /* To avoid redundant close_stdout diagnostic. */-
415 die (EXIT_FAILURE, errno, _("error writing %s"),-
416 quoteaf ("standard output"));-
417 }
never executed: end of block
0
418}
executed 280 times by 1 test: end of block
Executed by:
  • tail
280
419-
420/* Read and output N_BYTES of file PRETTY_FILENAME starting at the current-
421 position in FD. If N_BYTES is COPY_TO_EOF, then copy until end of file.-
422 If N_BYTES is COPY_A_BUFFER, then copy at most one buffer's worth.-
423 Return the number of bytes read from the file. */-
424-
425static uintmax_t-
426dump_remainder (bool want_header, const char *pretty_filename, int fd,-
427 uintmax_t n_bytes)-
428{-
429 uintmax_t n_written;-
430 uintmax_t n_remaining = n_bytes;-
431-
432 n_written = 0;-
433 while (1)-
434 {-
435 char buffer[BUFSIZ];-
436 size_t n = MIN (n_remaining, BUFSIZ);
(( n_remaining )<(8192))Description
TRUEevaluated 107 times by 1 test
Evaluated by:
  • tail
FALSEevaluated 230 times by 1 test
Evaluated by:
  • tail
107-230
437 size_t bytes_read = safe_read (fd, buffer, n);-
438 if (bytes_read == SAFE_READ_ERROR)
bytes_read == ((size_t) -1)Description
TRUEnever evaluated
FALSEevaluated 337 times by 1 test
Evaluated by:
  • tail
0-337
439 {-
440 if (errno != EAGAIN)
(*__errno_location ()) != 11Description
TRUEnever evaluated
FALSEnever evaluated
0
441 die (EXIT_FAILURE, errno, _("error reading %s"),
never executed: ((!!sizeof (struct { _Static_assert ( 1 , "verify_expr (" "1" ", " "(error (1, (*__errno_location ()), dcgettext (((void *)0), \"error reading %s\", 5), quotearg_style (shell_escape_always_quoting_style, pretty_filename)), assume (false))" ")"); int _gl_d... ) ? (void) 0 : __builtin_unreachable ()))) : ((error ( 1 , (*__errno_location ()) , dcgettext (((void *)0), "error reading %s" , 5) , quotearg_style (shell_escape_always_quoting_style, pretty_filename)), (( 0 ) ? (void) 0 : __builtin_unreachable ())))) ;
0
442 quoteaf (pretty_filename));
never executed: ((!!sizeof (struct { _Static_assert ( 1 , "verify_expr (" "1" ", " "(error (1, (*__errno_location ()), dcgettext (((void *)0), \"error reading %s\", 5), quotearg_style (shell_escape_always_quoting_style, pretty_filename)), assume (false))" ")"); int _gl_d... ) ? (void) 0 : __builtin_unreachable ()))) : ((error ( 1 , (*__errno_location ()) , dcgettext (((void *)0), "error reading %s" , 5) , quotearg_style (shell_escape_always_quoting_style, pretty_filename)), (( 0 ) ? (void) 0 : __builtin_unreachable ())))) ;
0
443 break;
never executed: break;
0
444 }-
445 if (bytes_read == 0)
bytes_read == 0Description
TRUEevaluated 147 times by 1 test
Evaluated by:
  • tail
FALSEevaluated 190 times by 1 test
Evaluated by:
  • tail
147-190
446 break;
executed 147 times by 1 test: break;
Executed by:
  • tail
147
447 if (want_header)
want_headerDescription
TRUEevaluated 3 times by 1 test
Evaluated by:
  • tail
FALSEevaluated 187 times by 1 test
Evaluated by:
  • tail
3-187
448 {-
449 write_header (pretty_filename);-
450 want_header = false;-
451 }
executed 3 times by 1 test: end of block
Executed by:
  • tail
3
452 xwrite_stdout (buffer, bytes_read);-
453 n_written += bytes_read;-
454 if (n_bytes != COPY_TO_EOF)
n_bytes != (18...73709551615UL)Description
TRUEevaluated 86 times by 1 test
Evaluated by:
  • tail
FALSEevaluated 104 times by 1 test
Evaluated by:
  • tail
86-104
455 {-
456 n_remaining -= bytes_read;-
457 if (n_remaining == 0 || n_bytes == COPY_A_BUFFER)
n_remaining == 0Description
TRUEevaluated 85 times by 1 test
Evaluated by:
  • tail
FALSEevaluated 1 time by 1 test
Evaluated by:
  • tail
n_bytes == ( (...551615UL) - 1)Description
TRUEnever evaluated
FALSEevaluated 1 time by 1 test
Evaluated by:
  • tail
0-85
458 break;
executed 85 times by 1 test: break;
Executed by:
  • tail
85
459 }
executed 1 time by 1 test: end of block
Executed by:
  • tail
1
460 }
executed 105 times by 1 test: end of block
Executed by:
  • tail
105
461-
462 return n_written;
executed 232 times by 1 test: return n_written;
Executed by:
  • tail
232
463}-
464-
465/* Call lseek with the specified arguments, where file descriptor FD-
466 corresponds to the file, FILENAME.-
467 Give a diagnostic and exit nonzero if lseek fails.-
468 Otherwise, return the resulting offset. */-
469-
470static off_t-
471xlseek (int fd, off_t offset, int whence, char const *filename)-
472{-
473 off_t new_offset = lseek (fd, offset, whence);-
474 char buf[INT_BUFSIZE_BOUND (offset)];-
475 char *s;-
476-
477 if (0 <= new_offset)
0 <= new_offsetDescription
TRUEevaluated 527 times by 1 test
Evaluated by:
  • tail
FALSEnever evaluated
0-527
478 return new_offset;
executed 527 times by 1 test: return new_offset;
Executed by:
  • tail
527
479-
480 s = offtostr (offset, buf);-
481 switch (whence)-
482 {-
483 case SEEK_SET:
never executed: case 0 :
0
484 error (0, errno, _("%s: cannot seek to offset %s"),-
485 quotef (filename), s);-
486 break;
never executed: break;
0
487 case SEEK_CUR:
never executed: case 1 :
0
488 error (0, errno, _("%s: cannot seek to relative offset %s"),-
489 quotef (filename), s);-
490 break;
never executed: break;
0
491 case SEEK_END:
never executed: case 2 :
0
492 error (0, errno, _("%s: cannot seek to end-relative offset %s"),-
493 quotef (filename), s);-
494 break;
never executed: break;
0
495 default:
never executed: default:
0
496 abort ();
never executed: abort ();
0
497 }-
498-
499 exit (EXIT_FAILURE);
never executed: exit ( 1 );
0
500}-
501-
502/* Print the last N_LINES lines from the end of file FD.-
503 Go backward through the file, reading 'BUFSIZ' bytes at a time (except-
504 probably the first), until we hit the start of the file or have-
505 read NUMBER newlines.-
506 START_POS is the starting position of the read pointer for the file-
507 associated with FD (may be nonzero).-
508 END_POS is the file offset of EOF (one larger than offset of last byte).-
509 Return true if successful. */-
510-
511static bool-
512file_lines (const char *pretty_filename, int fd, uintmax_t n_lines,-
513 off_t start_pos, off_t end_pos, uintmax_t *read_pos)-
514{-
515 char buffer[BUFSIZ];-
516 size_t bytes_read;-
517 off_t pos = end_pos;-
518-
519 if (n_lines == 0)
n_lines == 0Description
TRUEevaluated 2 times by 1 test
Evaluated by:
  • tail
FALSEevaluated 103 times by 1 test
Evaluated by:
  • tail
2-103
520 return true;
executed 2 times by 1 test: return 1 ;
Executed by:
  • tail
2
521-
522 /* Set 'bytes_read' to the size of the last, probably partial, buffer;-
523 0 < 'bytes_read' <= 'BUFSIZ'. */-
524 bytes_read = (pos - start_pos) % BUFSIZ;-
525 if (bytes_read == 0)
bytes_read == 0Description
TRUEnever evaluated
FALSEevaluated 103 times by 1 test
Evaluated by:
  • tail
0-103
526 bytes_read = BUFSIZ;
never executed: bytes_read = 8192 ;
0
527 /* Make 'pos' a multiple of 'BUFSIZ' (0 if the file is short), so that all-
528 reads will be on block boundaries, which might increase efficiency. */-
529 pos -= bytes_read;-
530 xlseek (fd, pos, SEEK_SET, pretty_filename);-
531 bytes_read = safe_read (fd, buffer, bytes_read);-
532 if (bytes_read == SAFE_READ_ERROR)
bytes_read == ((size_t) -1)Description
TRUEnever evaluated
FALSEevaluated 103 times by 1 test
Evaluated by:
  • tail
0-103
533 {-
534 error (0, errno, _("error reading %s"), quoteaf (pretty_filename));-
535 return false;
never executed: return 0 ;
0
536 }-
537 *read_pos = pos + bytes_read;-
538-
539 /* Count the incomplete line on files that don't end with a newline. */-
540 if (bytes_read && buffer[bytes_read - 1] != line_end)
bytes_readDescription
TRUEevaluated 103 times by 1 test
Evaluated by:
  • tail
FALSEnever evaluated
buffer[bytes_r...1] != line_endDescription
TRUEevaluated 19 times by 1 test
Evaluated by:
  • tail
FALSEevaluated 84 times by 1 test
Evaluated by:
  • tail
0-103
541 --n_lines;
executed 19 times by 1 test: --n_lines;
Executed by:
  • tail
19
542-
543 do-
544 {-
545 /* Scan backward, counting the newlines in this bufferfull. */-
546-
547 size_t n = bytes_read;-
548 while (n)
nDescription
TRUEevaluated 290 times by 1 test
Evaluated by:
  • tail
FALSEnever evaluated
0-290
549 {-
550 char const *nl;-
551 nl = memrchr (buffer, line_end, n);-
552 if (nl == NULL)
nl == ((void *)0)Description
TRUEevaluated 83 times by 1 test
Evaluated by:
  • tail
FALSEevaluated 207 times by 1 test
Evaluated by:
  • tail
83-207
553 break;
executed 83 times by 1 test: break;
Executed by:
  • tail
83
554 n = nl - buffer;-
555 if (n_lines-- == 0)
n_lines-- == 0Description
TRUEevaluated 20 times by 1 test
Evaluated by:
  • tail
FALSEevaluated 187 times by 1 test
Evaluated by:
  • tail
20-187
556 {-
557 /* If this newline isn't the last character in the buffer,-
558 output the part that is after it. */-
559 if (n != bytes_read - 1)
n != bytes_read - 1Description
TRUEevaluated 20 times by 1 test
Evaluated by:
  • tail
FALSEnever evaluated
0-20
560 xwrite_stdout (nl + 1, bytes_read - (n + 1));
executed 20 times by 1 test: xwrite_stdout (nl + 1, bytes_read - (n + 1));
Executed by:
  • tail
20
561 *read_pos += dump_remainder (false, pretty_filename, fd,-
562 end_pos - (pos + bytes_read));-
563 return true;
executed 20 times by 1 test: return 1 ;
Executed by:
  • tail
20
564 }-
565 }
executed 187 times by 1 test: end of block
Executed by:
  • tail
187
566-
567 /* Not enough newlines in that bufferfull. */-
568 if (pos == start_pos)
pos == start_posDescription
TRUEevaluated 83 times by 1 test
Evaluated by:
  • tail
FALSEnever evaluated
0-83
569 {-
570 /* Not enough lines in the file; print everything from-
571 start_pos to the end. */-
572 xlseek (fd, start_pos, SEEK_SET, pretty_filename);-
573 *read_pos = start_pos + dump_remainder (false, pretty_filename, fd,-
574 end_pos);-
575 return true;
executed 83 times by 1 test: return 1 ;
Executed by:
  • tail
83
576 }-
577 pos -= BUFSIZ;-
578 xlseek (fd, pos, SEEK_SET, pretty_filename);-
579-
580 bytes_read = safe_read (fd, buffer, BUFSIZ);-
581 if (bytes_read == SAFE_READ_ERROR)
bytes_read == ((size_t) -1)Description
TRUEnever evaluated
FALSEnever evaluated
0
582 {-
583 error (0, errno, _("error reading %s"), quoteaf (pretty_filename));-
584 return false;
never executed: return 0 ;
0
585 }-
586-
587 *read_pos = pos + bytes_read;-
588 }
never executed: end of block
0
589 while (bytes_read > 0);
bytes_read > 0Description
TRUEnever evaluated
FALSEnever evaluated
0
590-
591 return true;
never executed: return 1 ;
0
592}-
593-
594/* Print the last N_LINES lines from the end of the standard input,-
595 open for reading as pipe FD.-
596 Buffer the text as a linked list of LBUFFERs, adding them as needed.-
597 Return true if successful. */-
598-
599static bool-
600pipe_lines (const char *pretty_filename, int fd, uintmax_t n_lines,-
601 uintmax_t *read_pos)-
602{-
603 struct linebuffer-
604 {-
605 char buffer[BUFSIZ];-
606 size_t nbytes;-
607 size_t nlines;-
608 struct linebuffer *next;-
609 };-
610 typedef struct linebuffer LBUFFER;-
611 LBUFFER *first, *last, *tmp;-
612 size_t total_lines = 0; /* Total number of newlines in all buffers. */-
613 bool ok = true;-
614 size_t n_read; /* Size in bytes of most recent read */-
615-
616 first = last = xmalloc (sizeof (LBUFFER));-
617 first->nbytes = first->nlines = 0;-
618 first->next = NULL;-
619 tmp = xmalloc (sizeof (LBUFFER));-
620-
621 /* Input is always read into a fresh buffer. */-
622 while (1)-
623 {-
624 n_read = safe_read (fd, tmp->buffer, BUFSIZ);-
625 if (n_read == 0 || n_read == SAFE_READ_ERROR)
n_read == 0Description
TRUEevaluated 64 times by 1 test
Evaluated by:
  • tail
FALSEevaluated 21 times by 1 test
Evaluated by:
  • tail
n_read == ((size_t) -1)Description
TRUEevaluated 2 times by 1 test
Evaluated by:
  • tail
FALSEevaluated 19 times by 1 test
Evaluated by:
  • tail
2-64
626 break;
executed 66 times by 1 test: break;
Executed by:
  • tail
66
627 tmp->nbytes = n_read;-
628 *read_pos += n_read;-
629 tmp->nlines = 0;-
630 tmp->next = NULL;-
631-
632 /* Count the number of newlines just read. */-
633 {-
634 char const *buffer_end = tmp->buffer + n_read;-
635 char const *p = tmp->buffer;-
636 while ((p = memchr (p, line_end, buffer_end - p)))
(p = memchr (p...ffer_end - p))Description
TRUEevaluated 67 times by 1 test
Evaluated by:
  • tail
FALSEevaluated 19 times by 1 test
Evaluated by:
  • tail
19-67
637 {-
638 ++p;-
639 ++tmp->nlines;-
640 }
executed 67 times by 1 test: end of block
Executed by:
  • tail
67
641 }-
642 total_lines += tmp->nlines;-
643-
644 /* If there is enough room in the last buffer read, just append the new-
645 one to it. This is because when reading from a pipe, 'n_read' can-
646 often be very small. */-
647 if (tmp->nbytes + last->nbytes < BUFSIZ)
tmp->nbytes + ...>nbytes < 8192Description
TRUEevaluated 19 times by 1 test
Evaluated by:
  • tail
FALSEnever evaluated
0-19
648 {-
649 memcpy (&last->buffer[last->nbytes], tmp->buffer, tmp->nbytes);-
650 last->nbytes += tmp->nbytes;-
651 last->nlines += tmp->nlines;-
652 }
executed 19 times by 1 test: end of block
Executed by:
  • tail
19
653 else-
654 {-
655 /* If there's not enough room, link the new buffer onto the end of-
656 the list, then either free up the oldest buffer for the next-
657 read if that would leave enough lines, or else malloc a new one.-
658 Some compaction mechanism is possible but probably not-
659 worthwhile. */-
660 last = last->next = tmp;-
661 if (total_lines - first->nlines > n_lines)
total_lines - ...ines > n_linesDescription
TRUEnever evaluated
FALSEnever evaluated
0
662 {-
663 tmp = first;-
664 total_lines -= first->nlines;-
665 first = first->next;-
666 }
never executed: end of block
0
667 else-
668 tmp = xmalloc (sizeof (LBUFFER));
never executed: tmp = xmalloc (sizeof (LBUFFER));
0
669 }-
670 }-
671-
672 free (tmp);-
673-
674 if (n_read == SAFE_READ_ERROR)
n_read == ((size_t) -1)Description
TRUEevaluated 2 times by 1 test
Evaluated by:
  • tail
FALSEevaluated 64 times by 1 test
Evaluated by:
  • tail
2-64
675 {-
676 error (0, errno, _("error reading %s"), quoteaf (pretty_filename));-
677 ok = false;-
678 goto free_lbuffers;
executed 2 times by 1 test: goto free_lbuffers;
Executed by:
  • tail
2
679 }-
680-
681 /* If the file is empty, then bail out. */-
682 if (last->nbytes == 0)
last->nbytes == 0Description
TRUEevaluated 45 times by 1 test
Evaluated by:
  • tail
FALSEevaluated 19 times by 1 test
Evaluated by:
  • tail
19-45
683 goto free_lbuffers;
executed 45 times by 1 test: goto free_lbuffers;
Executed by:
  • tail
45
684-
685 /* This prevents a core dump when the pipe contains no newlines. */-
686 if (n_lines == 0)
n_lines == 0Description
TRUEnever evaluated
FALSEevaluated 19 times by 1 test
Evaluated by:
  • tail
0-19
687 goto free_lbuffers;
never executed: goto free_lbuffers;
0
688-
689 /* Count the incomplete line on files that don't end with a newline. */-
690 if (last->buffer[last->nbytes - 1] != line_end)
last->buffer[l...1] != line_endDescription
TRUEevaluated 10 times by 1 test
Evaluated by:
  • tail
FALSEevaluated 9 times by 1 test
Evaluated by:
  • tail
9-10
691 {-
692 ++last->nlines;-
693 ++total_lines;-
694 }
executed 10 times by 1 test: end of block
Executed by:
  • tail
10
695-
696 /* Run through the list, printing lines. First, skip over unneeded-
697 buffers. */-
698 for (tmp = first; total_lines - tmp->nlines > n_lines; tmp = tmp->next)
total_lines - ...ines > n_linesDescription
TRUEnever evaluated
FALSEevaluated 19 times by 1 test
Evaluated by:
  • tail
0-19
699 total_lines -= tmp->nlines;
never executed: total_lines -= tmp->nlines;
0
700-
701 /* Find the correct beginning, then print the rest of the file. */-
702 {-
703 char const *beg = tmp->buffer;-
704 char const *buffer_end = tmp->buffer + tmp->nbytes;-
705 if (total_lines > n_lines)
total_lines > n_linesDescription
TRUEevaluated 14 times by 1 test
Evaluated by:
  • tail
FALSEevaluated 5 times by 1 test
Evaluated by:
  • tail
5-14
706 {-
707 /* Skip 'total_lines' - 'n_lines' newlines. We made sure that-
708 'total_lines' - 'n_lines' <= 'tmp->nlines'. */-
709 size_t j;-
710 for (j = total_lines - n_lines; j; --j)
jDescription
TRUEevaluated 21 times by 1 test
Evaluated by:
  • tail
FALSEevaluated 14 times by 1 test
Evaluated by:
  • tail
14-21
711 {-
712 beg = memchr (beg, line_end, buffer_end - beg);-
713 assert (beg);-
714 ++beg;-
715 }
executed 21 times by 1 test: end of block
Executed by:
  • tail
21
716 }
executed 14 times by 1 test: end of block
Executed by:
  • tail
14
717-
718 xwrite_stdout (beg, buffer_end - beg);-
719 }-
720-
721 for (tmp = tmp->next; tmp; tmp = tmp->next)
tmpDescription
TRUEnever evaluated
FALSEevaluated 19 times by 1 test
Evaluated by:
  • tail
0-19
722 xwrite_stdout (tmp->buffer, tmp->nbytes);
never executed: xwrite_stdout (tmp->buffer, tmp->nbytes);
0
723-
724free_lbuffers:
code before this statement executed 19 times by 1 test: free_lbuffers:
Executed by:
  • tail
19
725 while (first)
firstDescription
TRUEevaluated 66 times by 1 test
Evaluated by:
  • tail
FALSEevaluated 66 times by 1 test
Evaluated by:
  • tail
66
726 {-
727 tmp = first->next;-
728 free (first);-
729 first = tmp;-
730 }
executed 66 times by 1 test: end of block
Executed by:
  • tail
66
731 return ok;
executed 66 times by 1 test: return ok;
Executed by:
  • tail
66
732}-
733-
734/* Print the last N_BYTES characters from the end of pipe FD.-
735 This is a stripped down version of pipe_lines.-
736 Return true if successful. */-
737-
738static bool-
739pipe_bytes (const char *pretty_filename, int fd, uintmax_t n_bytes,-
740 uintmax_t *read_pos)-
741{-
742 struct charbuffer-
743 {-
744 char buffer[BUFSIZ];-
745 size_t nbytes;-
746 struct charbuffer *next;-
747 };-
748 typedef struct charbuffer CBUFFER;-
749 CBUFFER *first, *last, *tmp;-
750 size_t i; /* Index into buffers. */-
751 size_t total_bytes = 0; /* Total characters in all buffers. */-
752 bool ok = true;-
753 size_t n_read;-
754-
755 first = last = xmalloc (sizeof (CBUFFER));-
756 first->nbytes = 0;-
757 first->next = NULL;-
758 tmp = xmalloc (sizeof (CBUFFER));-
759-
760 /* Input is always read into a fresh buffer. */-
761 while (1)-
762 {-
763 n_read = safe_read (fd, tmp->buffer, BUFSIZ);-
764 if (n_read == 0 || n_read == SAFE_READ_ERROR)
n_read == 0Description
TRUEevaluated 35 times by 1 test
Evaluated by:
  • tail
FALSEevaluated 33 times by 1 test
Evaluated by:
  • tail
n_read == ((size_t) -1)Description
TRUEnever evaluated
FALSEevaluated 33 times by 1 test
Evaluated by:
  • tail
0-35
765 break;
executed 35 times by 1 test: break;
Executed by:
  • tail
35
766 *read_pos += n_read;-
767 tmp->nbytes = n_read;-
768 tmp->next = NULL;-
769-
770 total_bytes += tmp->nbytes;-
771 /* If there is enough room in the last buffer read, just append the new-
772 one to it. This is because when reading from a pipe, 'nbytes' can-
773 often be very small. */-
774 if (tmp->nbytes + last->nbytes < BUFSIZ)
tmp->nbytes + ...>nbytes < 8192Description
TRUEevaluated 33 times by 1 test
Evaluated by:
  • tail
FALSEnever evaluated
0-33
775 {-
776 memcpy (&last->buffer[last->nbytes], tmp->buffer, tmp->nbytes);-
777 last->nbytes += tmp->nbytes;-
778 }
executed 33 times by 1 test: end of block
Executed by:
  • tail
33
779 else-
780 {-
781 /* If there's not enough room, link the new buffer onto the end of-
782 the list, then either free up the oldest buffer for the next-
783 read if that would leave enough characters, or else malloc a new-
784 one. Some compaction mechanism is possible but probably not-
785 worthwhile. */-
786 last = last->next = tmp;-
787 if (total_bytes - first->nbytes > n_bytes)
total_bytes - ...ytes > n_bytesDescription
TRUEnever evaluated
FALSEnever evaluated
0
788 {-
789 tmp = first;-
790 total_bytes -= first->nbytes;-
791 first = first->next;-
792 }
never executed: end of block
0
793 else-
794 {-
795 tmp = xmalloc (sizeof (CBUFFER));-
796 }
never executed: end of block
0
797 }-
798 }-
799-
800 free (tmp);-
801-
802 if (n_read == SAFE_READ_ERROR)
n_read == ((size_t) -1)Description
TRUEnever evaluated
FALSEevaluated 35 times by 1 test
Evaluated by:
  • tail
0-35
803 {-
804 error (0, errno, _("error reading %s"), quoteaf (pretty_filename));-
805 ok = false;-
806 goto free_cbuffers;
never executed: goto free_cbuffers;
0
807 }-
808-
809 /* Run through the list, printing characters. First, skip over unneeded-
810 buffers. */-
811 for (tmp = first; total_bytes - tmp->nbytes > n_bytes; tmp = tmp->next)
total_bytes - ...ytes > n_bytesDescription
TRUEnever evaluated
FALSEevaluated 35 times by 1 test
Evaluated by:
  • tail
0-35
812 total_bytes -= tmp->nbytes;
never executed: total_bytes -= tmp->nbytes;
0
813-
814 /* Find the correct beginning, then print the rest of the file.-
815 We made sure that 'total_bytes' - 'n_bytes' <= 'tmp->nbytes'. */-
816 if (total_bytes > n_bytes)
total_bytes > n_bytesDescription
TRUEevaluated 30 times by 1 test
Evaluated by:
  • tail
FALSEevaluated 5 times by 1 test
Evaluated by:
  • tail
5-30
817 i = total_bytes - n_bytes;
executed 30 times by 1 test: i = total_bytes - n_bytes;
Executed by:
  • tail
30
818 else-
819 i = 0;
executed 5 times by 1 test: i = 0;
Executed by:
  • tail
5
820 xwrite_stdout (&tmp->buffer[i], tmp->nbytes - i);-
821-
822 for (tmp = tmp->next; tmp; tmp = tmp->next)
tmpDescription
TRUEnever evaluated
FALSEevaluated 35 times by 1 test
Evaluated by:
  • tail
0-35
823 xwrite_stdout (tmp->buffer, tmp->nbytes);
never executed: xwrite_stdout (tmp->buffer, tmp->nbytes);
0
824-
825free_cbuffers:
code before this statement executed 35 times by 1 test: free_cbuffers:
Executed by:
  • tail
35
826 while (first)
firstDescription
TRUEevaluated 35 times by 1 test
Evaluated by:
  • tail
FALSEevaluated 35 times by 1 test
Evaluated by:
  • tail
35
827 {-
828 tmp = first->next;-
829 free (first);-
830 first = tmp;-
831 }
executed 35 times by 1 test: end of block
Executed by:
  • tail
35
832 return ok;
executed 35 times by 1 test: return ok;
Executed by:
  • tail
35
833}-
834-
835/* Skip N_BYTES characters from the start of pipe FD, and print-
836 any extra characters that were read beyond that.-
837 Return 1 on error, 0 if ok, -1 if EOF. */-
838-
839static int-
840start_bytes (const char *pretty_filename, int fd, uintmax_t n_bytes,-
841 uintmax_t *read_pos)-
842{-
843 char buffer[BUFSIZ];-
844-
845 while (0 < n_bytes)
0 < n_bytesDescription
TRUEevaluated 4 times by 1 test
Evaluated by:
  • tail
FALSEnever evaluated
0-4
846 {-
847 size_t bytes_read = safe_read (fd, buffer, BUFSIZ);-
848 if (bytes_read == 0)
bytes_read == 0Description
TRUEevaluated 1 time by 1 test
Evaluated by:
  • tail
FALSEevaluated 3 times by 1 test
Evaluated by:
  • tail
1-3
849 return -1;
executed 1 time by 1 test: return -1;
Executed by:
  • tail
1
850 if (bytes_read == SAFE_READ_ERROR)
bytes_read == ((size_t) -1)Description
TRUEnever evaluated
FALSEevaluated 3 times by 1 test
Evaluated by:
  • tail
0-3
851 {-
852 error (0, errno, _("error reading %s"), quoteaf (pretty_filename));-
853 return 1;
never executed: return 1;
0
854 }-
855 *read_pos += bytes_read;-
856 if (bytes_read <= n_bytes)
bytes_read <= n_bytesDescription
TRUEevaluated 1 time by 1 test
Evaluated by:
  • tail
FALSEevaluated 2 times by 1 test
Evaluated by:
  • tail
1-2
857 n_bytes -= bytes_read;
executed 1 time by 1 test: n_bytes -= bytes_read;
Executed by:
  • tail
1
858 else-
859 {-
860 size_t n_remaining = bytes_read - n_bytes;-
861 if (n_remaining)
n_remainingDescription
TRUEevaluated 2 times by 1 test
Evaluated by:
  • tail
FALSEnever evaluated
0-2
862 xwrite_stdout (&buffer[n_bytes], n_remaining);
executed 2 times by 1 test: xwrite_stdout (&buffer[n_bytes], n_remaining);
Executed by:
  • tail
2
863 break;
executed 2 times by 1 test: break;
Executed by:
  • tail
2
864 }-
865 }-
866-
867 return 0;
executed 2 times by 1 test: return 0;
Executed by:
  • tail
2
868}-
869-
870/* Skip N_LINES lines at the start of file or pipe FD, and print-
871 any extra characters that were read beyond that.-
872 Return 1 on error, 0 if ok, -1 if EOF. */-
873-
874static int-
875start_lines (const char *pretty_filename, int fd, uintmax_t n_lines,-
876 uintmax_t *read_pos)-
877{-
878 if (n_lines == 0)
n_lines == 0Description
TRUEevaluated 12 times by 1 test
Evaluated by:
  • tail
FALSEevaluated 14 times by 1 test
Evaluated by:
  • tail
12-14
879 return 0;
executed 12 times by 1 test: return 0;
Executed by:
  • tail
12
880-
881 while (1)-
882 {-
883 char buffer[BUFSIZ];-
884 size_t bytes_read = safe_read (fd, buffer, BUFSIZ);-
885 if (bytes_read == 0) /* EOF */
bytes_read == 0Description
TRUEnever evaluated
FALSEevaluated 14 times by 1 test
Evaluated by:
  • tail
0-14
886 return -1;
never executed: return -1;
0
887 if (bytes_read == SAFE_READ_ERROR) /* error */
bytes_read == ((size_t) -1)Description
TRUEnever evaluated
FALSEevaluated 14 times by 1 test
Evaluated by:
  • tail
0-14
888 {-
889 error (0, errno, _("error reading %s"), quoteaf (pretty_filename));-
890 return 1;
never executed: return 1;
0
891 }-
892-
893 char *buffer_end = buffer + bytes_read;-
894-
895 *read_pos += bytes_read;-
896-
897 char *p = buffer;-
898 while ((p = memchr (p, line_end, buffer_end - p)))
(p = memchr (p...ffer_end - p))Description
TRUEevaluated 62 times by 1 test
Evaluated by:
  • tail
FALSEnever evaluated
0-62
899 {-
900 ++p;-
901 if (--n_lines == 0)
--n_lines == 0Description
TRUEevaluated 14 times by 1 test
Evaluated by:
  • tail
FALSEevaluated 48 times by 1 test
Evaluated by:
  • tail
14-48
902 {-
903 if (p < buffer_end)
p < buffer_endDescription
TRUEevaluated 14 times by 1 test
Evaluated by:
  • tail
FALSEnever evaluated
0-14
904 xwrite_stdout (p, buffer_end - p);
executed 14 times by 1 test: xwrite_stdout (p, buffer_end - p);
Executed by:
  • tail
14
905 return 0;
executed 14 times by 1 test: return 0;
Executed by:
  • tail
14
906 }-
907 }
executed 48 times by 1 test: end of block
Executed by:
  • tail
48
908 }
never executed: end of block
0
909}
never executed: end of block
0
910-
911/* Return false when FD is open on a file residing on a local file system.-
912 If fstatfs fails, give a diagnostic and return true.-
913 If fstatfs cannot be called, return true. */-
914static bool-
915fremote (int fd, const char *name)-
916{-
917 bool remote = true; /* be conservative (poll by default). */-
918-
919#if HAVE_FSTATFS && HAVE_STRUCT_STATFS_F_TYPE && defined __linux__-
920 struct statfs buf;-
921 int err = fstatfs (fd, &buf);-
922 if (err != 0)
err != 0Description
TRUEnever evaluated
FALSEevaluated 970 times by 1 test
Evaluated by:
  • tail
0-970
923 {-
924 /* On at least linux-2.6.38, fstatfs fails with ENOSYS when FD-
925 is open on a pipe. Treat that like a remote file. */-
926 if (errno != ENOSYS)
(*__errno_location ()) != 38Description
TRUEnever evaluated
FALSEnever evaluated
0
927 error (0, errno, _("cannot determine location of %s. "
never executed: error (0, (*__errno_location ()) , dcgettext (((void *)0), "cannot determine location of %s. " "reverting to polling" , 5) , quotearg_style (shell_escape_always_quoting_style, name));
0
928 "reverting to polling"), quoteaf (name));
never executed: error (0, (*__errno_location ()) , dcgettext (((void *)0), "cannot determine location of %s. " "reverting to polling" , 5) , quotearg_style (shell_escape_always_quoting_style, name));
0
929 }
never executed: end of block
0
930 else-
931 {-
932 switch (is_local_fs_type (buf.f_type))-
933 {-
934 case 0:
executed 5 times by 1 test: case 0:
Executed by:
  • tail
5
935 break;
executed 5 times by 1 test: break;
Executed by:
  • tail
5
936 case -1:
never executed: case -1:
0
937 /* Treat unrecognized file systems as "remote", so caller polls.-
938 Note README-release has instructions for syncing the internal-
939 list with the latest Linux kernel file system constants. */-
940 break;
never executed: break;
0
941 case 1:
executed 965 times by 1 test: case 1:
Executed by:
  • tail
965
942 remote = false;-
943 break;
executed 965 times by 1 test: break;
Executed by:
  • tail
965
944 default:
never executed: default:
0
945 assert (!"unexpected return value from is_local_fs_type");-
946 }
never executed: end of block
0
947 }-
948#endif-
949-
950 return remote;
executed 970 times by 1 test: return remote;
Executed by:
  • tail
970
951}-
952-
953/* open/fstat F->name and handle changes. */-
954static void-
955recheck (struct File_spec *f, bool blocking)-
956{-
957 struct stat new_stats;-
958 bool ok = true;-
959 bool is_stdin = (STREQ (f->name, "-"));
never executed: __result = (((const unsigned char *) (const char *) ( f->name ))[3] - __s2[3]);
never executed: end of block
never executed: end of block
never executed: __result = (((const unsigned char *) (const char *) ( "-" ))[3] - __s2[3]);
never executed: end of block
never executed: end of block
__s1_len > 0Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s1_len > 1Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s1_len > 2Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s2_len > 0Description
TRUEevaluated 1113 times by 1 test
Evaluated by:
  • tail
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEevaluated 1113 times by 1 test
Evaluated by:
  • tail
__s2_len > 1Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s2_len > 2Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
0-1113
960 bool was_tailable = f->tailable;-
961 int prev_errnum = f->errnum;-
962 bool new_file;-
963 int fd = (is_stdin
is_stdinDescription
TRUEnever evaluated
FALSEevaluated 1113 times by 1 test
Evaluated by:
  • tail
0-1113
964 ? STDIN_FILENO-
965 : open (f->name, O_RDONLY | (blocking ? 0 : O_NONBLOCK)));-
966-
967 assert (valid_file_spec (f));-
968-
969 /* If the open fails because the file doesn't exist,-
970 then mark the file as not tailable. */-
971 f->tailable = !(reopen_inaccessible_files && fd == -1);
reopen_inaccessible_filesDescription
TRUEevaluated 1100 times by 1 test
Evaluated by:
  • tail
FALSEevaluated 13 times by 1 test
Evaluated by:
  • tail
fd == -1Description
TRUEevaluated 263 times by 1 test
Evaluated by:
  • tail
FALSEevaluated 837 times by 1 test
Evaluated by:
  • tail
13-1100
972-
973 if (! disable_inotify && ! lstat (f->name, &new_stats)
! disable_inotifyDescription
TRUEevaluated 977 times by 1 test
Evaluated by:
  • tail
FALSEevaluated 136 times by 1 test
Evaluated by:
  • tail
! lstat (f->name, &new_stats)Description
TRUEevaluated 764 times by 1 test
Evaluated by:
  • tail
FALSEevaluated 213 times by 1 test
Evaluated by:
  • tail
136-977
974 && S_ISLNK (new_stats.st_mode))
(((( new_stats... == (0120000))Description
TRUEnever evaluated
FALSEevaluated 764 times by 1 test
Evaluated by:
  • tail
0-764
975 {-
976 /* Diagnose the edge case where a regular file is changed-
977 to a symlink. We avoid inotify with symlinks since-
978 it's awkward to match between symlink name and target. */-
979 ok = false;-
980 f->errnum = -1;-
981 f->ignore = true;-
982-
983 error (0, 0, _("%s has been replaced with an untailable symbolic link"),-
984 quoteaf (pretty_name (f)));-
985 }
never executed: end of block
0
986 else if (fd == -1 || fstat (fd, &new_stats) < 0)
fd == -1Description
TRUEevaluated 268 times by 1 test
Evaluated by:
  • tail
FALSEevaluated 845 times by 1 test
Evaluated by:
  • tail
fstat (fd, &new_stats) < 0Description
TRUEnever evaluated
FALSEevaluated 845 times by 1 test
Evaluated by:
  • tail
0-845
987 {-
988 ok = false;-
989 f->errnum = errno;-
990 if (!f->tailable)
!f->tailableDescription
TRUEevaluated 263 times by 1 test
Evaluated by:
  • tail
FALSEevaluated 5 times by 1 test
Evaluated by:
  • tail
5-263
991 {-
992 if (was_tailable)
was_tailableDescription
TRUEevaluated 215 times by 1 test
Evaluated by:
  • tail
FALSEevaluated 48 times by 1 test
Evaluated by:
  • tail
48-215
993 {-
994 /* FIXME-maybe: detect the case in which the file first becomes-
995 unreadable (perms), and later becomes readable again and can-
996 be seen to be the same file (dev/ino). Otherwise, tail prints-
997 the entire contents of the file when it becomes readable. */-
998 error (0, f->errnum, _("%s has become inaccessible"),-
999 quoteaf (pretty_name (f)));-
1000 }
executed 215 times by 1 test: end of block
Executed by:
  • tail
215
1001 else-
1002 {-
1003 /* say nothing... it's still not tailable */-
1004 }
executed 48 times by 1 test: end of block
Executed by:
  • tail
48
1005 }-
1006 else if (prev_errnum != errno)
prev_errnum !=...o_location ())Description
TRUEevaluated 2 times by 1 test
Evaluated by:
  • tail
FALSEevaluated 3 times by 1 test
Evaluated by:
  • tail
2-3
1007 error (0, errno, "%s", quotef (pretty_name (f)));
executed 2 times by 1 test: error (0, (*__errno_location ()) , "%s", quotearg_n_style_colon (0, shell_escape_quoting_style, pretty_name (f)));
Executed by:
  • tail
2
1008 }
executed 268 times by 1 test: end of block
Executed by:
  • tail
268
1009 else if (!IS_TAILABLE_FILE_TYPE (new_stats.st_mode))
(((( new_stats... == (0100000))Description
TRUEevaluated 841 times by 1 test
Evaluated by:
  • tail
FALSEevaluated 4 times by 1 test
Evaluated by:
  • tail
(((( new_stats... == (0010000))Description
TRUEnever evaluated
FALSEevaluated 4 times by 1 test
Evaluated by:
  • tail
(((( new_stats... == (0140000))Description
TRUEnever evaluated
FALSEevaluated 4 times by 1 test
Evaluated by:
  • tail
(((( new_stats... == (0020000))Description
TRUEnever evaluated
FALSEevaluated 4 times by 1 test
Evaluated by:
  • tail
0-841
1010 {-
1011 ok = false;-
1012 f->errnum = -1;-
1013 f->tailable = false;-
1014 f->ignore = ! (reopen_inaccessible_files && follow_mode == Follow_name);
reopen_inaccessible_filesDescription
TRUEevaluated 4 times by 1 test
Evaluated by:
  • tail
FALSEnever evaluated
follow_mode == Follow_nameDescription
TRUEevaluated 2 times by 1 test
Evaluated by:
  • tail
FALSEevaluated 2 times by 1 test
Evaluated by:
  • tail
0-4
1015 if (was_tailable || prev_errnum != f->errnum)
was_tailableDescription
TRUEnever evaluated
FALSEevaluated 4 times by 1 test
Evaluated by:
  • tail
prev_errnum != f->errnumDescription
TRUEevaluated 2 times by 1 test
Evaluated by:
  • tail
FALSEevaluated 2 times by 1 test
Evaluated by:
  • tail
0-4
1016 error (0, 0, _("%s has been replaced with an untailable file%s"),
executed 2 times by 1 test: error (0, 0, dcgettext (((void *)0), "%s has been replaced with an untailable file%s" , 5) , quotearg_style (shell_escape_always_quoting_style, pretty_name (f)), f->ignore ? dcgettext (((void *)0), "; giving up on this name" , 5) : "");
Executed by:
  • tail
2
1017 quoteaf (pretty_name (f)),
executed 2 times by 1 test: error (0, 0, dcgettext (((void *)0), "%s has been replaced with an untailable file%s" , 5) , quotearg_style (shell_escape_always_quoting_style, pretty_name (f)), f->ignore ? dcgettext (((void *)0), "; giving up on this name" , 5) : "");
Executed by:
  • tail
2
1018 f->ignore ? _("; giving up on this name") : "");
executed 2 times by 1 test: error (0, 0, dcgettext (((void *)0), "%s has been replaced with an untailable file%s" , 5) , quotearg_style (shell_escape_always_quoting_style, pretty_name (f)), f->ignore ? dcgettext (((void *)0), "; giving up on this name" , 5) : "");
Executed by:
  • tail
2
1019 }
executed 4 times by 1 test: end of block
Executed by:
  • tail
4
1020 else if ((f->remote = fremote (fd, pretty_name (f))) && ! disable_inotify)
(f->remote = f...tty_name (f)))Description
TRUEnever evaluated
FALSEevaluated 841 times by 1 test
Evaluated by:
  • tail
! disable_inotifyDescription
TRUEnever evaluated
FALSEnever evaluated
0-841
1021 {-
1022 ok = false;-
1023 f->errnum = -1;-
1024 error (0, 0, _("%s has been replaced with an untailable remote file"),-
1025 quoteaf (pretty_name (f)));-
1026 f->ignore = true;-
1027 f->remote = true;-
1028 }
never executed: end of block
0
1029 else-
1030 {-
1031 f->errnum = 0;-
1032 }
executed 841 times by 1 test: end of block
Executed by:
  • tail
841
1033-
1034 new_file = false;-
1035 if (!ok)
!okDescription
TRUEevaluated 272 times by 1 test
Evaluated by:
  • tail
FALSEevaluated 841 times by 1 test
Evaluated by:
  • tail
272-841
1036 {-
1037 close_fd (fd, pretty_name (f));-
1038 close_fd (f->fd, pretty_name (f));-
1039 f->fd = -1;-
1040 }
executed 272 times by 1 test: end of block
Executed by:
  • tail
272
1041 else if (prev_errnum && prev_errnum != ENOENT)
prev_errnumDescription
TRUEevaluated 230 times by 1 test
Evaluated by:
  • tail
FALSEevaluated 611 times by 1 test
Evaluated by:
  • tail
prev_errnum != 2Description
TRUEevaluated 2 times by 1 test
Evaluated by:
  • tail
FALSEevaluated 228 times by 1 test
Evaluated by:
  • tail
2-611
1042 {-
1043 new_file = true;-
1044 assert (f->fd == -1);-
1045 error (0, 0, _("%s has become accessible"), quoteaf (pretty_name (f)));-
1046 }
executed 2 times by 1 test: end of block
Executed by:
  • tail
2
1047 else if (f->fd == -1)
f->fd == -1Description
TRUEevaluated 228 times by 1 test
Evaluated by:
  • tail
FALSEevaluated 611 times by 1 test
Evaluated by:
  • tail
228-611
1048 {-
1049 /* A new file even when inodes haven't changed as <dev,inode>-
1050 pairs can be reused, and we know the file was missing-
1051 on the previous iteration. Note this also means the file-
1052 is redisplayed in --follow=name mode if renamed away from-
1053 and back to a monitored name. */-
1054 new_file = true;-
1055-
1056 error (0, 0,-
1057 _("%s has appeared; following new file"),-
1058 quoteaf (pretty_name (f)));-
1059 }
executed 228 times by 1 test: end of block
Executed by:
  • tail
228
1060 else if (f->ino != new_stats.st_ino || f->dev != new_stats.st_dev)
f->ino != new_stats.st_inoDescription
TRUEevaluated 52 times by 1 test
Evaluated by:
  • tail
FALSEevaluated 559 times by 1 test
Evaluated by:
  • tail
f->dev != new_stats.st_devDescription
TRUEnever evaluated
FALSEevaluated 559 times by 1 test
Evaluated by:
  • tail
0-559
1061 {-
1062 /* File has been replaced (e.g., via log rotation) ---
1063 tail the new one. */-
1064 new_file = true;-
1065-
1066 error (0, 0,-
1067 _("%s has been replaced; following new file"),-
1068 quoteaf (pretty_name (f)));-
1069-
1070 /* Close the old one. */-
1071 close_fd (f->fd, pretty_name (f));-
1072-
1073 }
executed 52 times by 1 test: end of block
Executed by:
  • tail
52
1074 else-
1075 {-
1076 /* No changes detected, so close new fd. */-
1077 close_fd (fd, pretty_name (f));-
1078 }
executed 559 times by 1 test: end of block
Executed by:
  • tail
559
1079-
1080 /* FIXME: When a log is rotated, daemons tend to log to the-
1081 old file descriptor until the new file is present and-
1082 the daemon is sent a signal. Therefore tail may miss entries-
1083 being written to the old file. Perhaps we should keep-
1084 the older file open and continue to monitor it until-
1085 data is written to a new file. */-
1086 if (new_file)
new_fileDescription
TRUEevaluated 282 times by 1 test
Evaluated by:
  • tail
FALSEevaluated 831 times by 1 test
Evaluated by:
  • tail
282-831
1087 {-
1088 /* Start at the beginning of the file. */-
1089 record_open_fd (f, fd, 0, &new_stats, (is_stdin ? -1 : blocking));-
1090 xlseek (fd, 0, SEEK_SET, pretty_name (f));-
1091 }
executed 282 times by 1 test: end of block
Executed by:
  • tail
282
1092}
executed 1113 times by 1 test: end of block
Executed by:
  • tail
1113
1093-
1094/* Return true if any of the N_FILES files in F are live, i.e., have-
1095 open file descriptors, or should be checked again (see --retry).-
1096 When following descriptors, checking should only continue when any-
1097 of the files is not yet ignored. */-
1098-
1099static bool-
1100any_live_files (const struct File_spec *f, size_t n_files)-
1101{-
1102 /* In inotify mode, ignore may be set for files-
1103 which may later be replaced with new files.-
1104 So always consider files live in -F mode. */-
1105 if (reopen_inaccessible_files && follow_mode == Follow_name)
reopen_inaccessible_filesDescription
TRUEevaluated 143 times by 1 test
Evaluated by:
  • tail
FALSEevaluated 160 times by 1 test
Evaluated by:
  • tail
follow_mode == Follow_nameDescription
TRUEevaluated 123 times by 1 test
Evaluated by:
  • tail
FALSEevaluated 20 times by 1 test
Evaluated by:
  • tail
20-160
1106 return true;
executed 123 times by 1 test: return 1 ;
Executed by:
  • tail
123
1107-
1108 for (size_t i = 0; i < n_files; i++)
i < n_filesDescription
TRUEevaluated 188 times by 1 test
Evaluated by:
  • tail
FALSEevaluated 14 times by 1 test
Evaluated by:
  • tail
14-188
1109 {-
1110 if (0 <= f[i].fd)
0 <= f[i].fdDescription
TRUEevaluated 162 times by 1 test
Evaluated by:
  • tail
FALSEevaluated 26 times by 1 test
Evaluated by:
  • tail
26-162
1111 return true;
executed 162 times by 1 test: return 1 ;
Executed by:
  • tail
162
1112 else-
1113 {-
1114 if (! f[i].ignore && reopen_inaccessible_files)
! f[i].ignoreDescription
TRUEevaluated 4 times by 1 test
Evaluated by:
  • tail
FALSEevaluated 22 times by 1 test
Evaluated by:
  • tail
reopen_inaccessible_filesDescription
TRUEevaluated 4 times by 1 test
Evaluated by:
  • tail
FALSEnever evaluated
0-22
1115 return true;
executed 4 times by 1 test: return 1 ;
Executed by:
  • tail
4
1116 }
executed 22 times by 1 test: end of block
Executed by:
  • tail
22
1117 }-
1118-
1119 return false;
executed 14 times by 1 test: return 0 ;
Executed by:
  • tail
14
1120}-
1121-
1122/* Tail N_FILES files forever, or until killed.-
1123 The pertinent information for each file is stored in an entry of F.-
1124 Loop over each of them, doing an fstat to see if they have changed size,-
1125 and an occasional open/fstat to see if any dev/ino pair has changed.-
1126 If none of them have changed size in one iteration, sleep for a-
1127 while and try again. Continue until the user interrupts us. */-
1128-
1129static void-
1130tail_forever (struct File_spec *f, size_t n_files, double sleep_interval)-
1131{-
1132 /* Use blocking I/O as an optimization, when it's easy. */-
1133 bool blocking = (pid == 0 && follow_mode == Follow_descriptor
pid == 0Description
TRUEevaluated 51 times by 1 test
Evaluated by:
  • tail
FALSEevaluated 5 times by 1 test
Evaluated by:
  • tail
follow_mode ==...low_descriptorDescription
TRUEevaluated 27 times by 1 test
Evaluated by:
  • tail
FALSEevaluated 24 times by 1 test
Evaluated by:
  • tail
5-51
1134 && n_files == 1 && f[0].fd != -1 && ! S_ISREG (f[0].mode));
n_files == 1Description
TRUEevaluated 23 times by 1 test
Evaluated by:
  • tail
FALSEevaluated 4 times by 1 test
Evaluated by:
  • tail
f[0].fd != -1Description
TRUEevaluated 12 times by 1 test
Evaluated by:
  • tail
FALSEevaluated 11 times by 1 test
Evaluated by:
  • tail
! (((( f[0].mo... == (0100000))Description
TRUEevaluated 1 time by 1 test
Evaluated by:
  • tail
FALSEevaluated 11 times by 1 test
Evaluated by:
  • tail
1-23
1135 size_t last;-
1136 bool writer_is_dead = false;-
1137-
1138 last = n_files - 1;-
1139-
1140 while (1)-
1141 {-
1142 size_t i;-
1143 bool any_input = false;-
1144-
1145 for (i = 0; i < n_files; i++)
i < n_filesDescription
TRUEevaluated 414 times by 1 test
Evaluated by:
  • tail
FALSEevaluated 303 times by 1 test
Evaluated by:
  • tail
303-414
1146 {-
1147 int fd;-
1148 char const *name;-
1149 mode_t mode;-
1150 struct stat stats;-
1151 uintmax_t bytes_read;-
1152-
1153 if (f[i].ignore)
f[i].ignoreDescription
TRUEevaluated 20 times by 1 test
Evaluated by:
  • tail
FALSEevaluated 394 times by 1 test
Evaluated by:
  • tail
20-394
1154 continue;
executed 20 times by 1 test: continue;
Executed by:
  • tail
20
1155-
1156 if (f[i].fd < 0)
f[i].fd < 0Description
TRUEevaluated 73 times by 1 test
Evaluated by:
  • tail
FALSEevaluated 321 times by 1 test
Evaluated by:
  • tail
73-321
1157 {-
1158 recheck (&f[i], blocking);-
1159 continue;
executed 73 times by 1 test: continue;
Executed by:
  • tail
73
1160 }-
1161-
1162 fd = f[i].fd;-
1163 name = pretty_name (&f[i]);-
1164 mode = f[i].mode;-
1165-
1166 if (f[i].blocking != blocking)
f[i].blocking != blockingDescription
TRUEevaluated 36 times by 1 test
Evaluated by:
  • tail
FALSEevaluated 285 times by 1 test
Evaluated by:
  • tail
36-285
1167 {-
1168 int old_flags = fcntl (fd, F_GETFL);-
1169 int new_flags = old_flags | (blocking ? 0 : O_NONBLOCK);-
1170 if (old_flags < 0
old_flags < 0Description
TRUEnever evaluated
FALSEevaluated 36 times by 1 test
Evaluated by:
  • tail
0-36
1171 || (new_flags != old_flags
new_flags != old_flagsDescription
TRUEevaluated 36 times by 1 test
Evaluated by:
  • tail
FALSEnever evaluated
0-36
1172 && fcntl (fd, F_SETFL, new_flags) == -1))
rpl_fcntl (fd,...w_flags) == -1Description
TRUEnever evaluated
FALSEevaluated 36 times by 1 test
Evaluated by:
  • tail
0-36
1173 {-
1174 /* Don't update f[i].blocking if fcntl fails. */-
1175 if (S_ISREG (f[i].mode) && errno == EPERM)
(((( f[i].mode... == (0100000))Description
TRUEnever evaluated
FALSEnever evaluated
(*__errno_location ()) == 1Description
TRUEnever evaluated
FALSEnever evaluated
0
1176 {-
1177 /* This happens when using tail -f on a file with-
1178 the append-only attribute. */-
1179 }
never executed: end of block
0
1180 else-
1181 die (EXIT_FAILURE, errno,
never executed: ((!!sizeof (struct { _Static_assert ( 1 , "verify_expr (" "1" ", " "(error (1, (*__errno_location ()), dcgettext (((void *)0), \"%s: cannot change nonblocking mode\", 5), quotearg_n_style_colon (0, shell_escape_quoting_style, name)), assume (false))" ")")... 0 : __builtin_unreachable ()))) : ((error ( 1 , (*__errno_location ()) , dcgettext (((void *)0), "%s: cannot change nonblocking mode" , 5) , quotearg_n_style_colon (0, shell_escape_quoting_style, name)), (( 0 ) ? (void) 0 : __builtin_unreachable ())))) ;
0
1182 _("%s: cannot change nonblocking mode"),
never executed: ((!!sizeof (struct { _Static_assert ( 1 , "verify_expr (" "1" ", " "(error (1, (*__errno_location ()), dcgettext (((void *)0), \"%s: cannot change nonblocking mode\", 5), quotearg_n_style_colon (0, shell_escape_quoting_style, name)), assume (false))" ")")... 0 : __builtin_unreachable ()))) : ((error ( 1 , (*__errno_location ()) , dcgettext (((void *)0), "%s: cannot change nonblocking mode" , 5) , quotearg_n_style_colon (0, shell_escape_quoting_style, name)), (( 0 ) ? (void) 0 : __builtin_unreachable ())))) ;
0
1183 quotef (name));
never executed: ((!!sizeof (struct { _Static_assert ( 1 , "verify_expr (" "1" ", " "(error (1, (*__errno_location ()), dcgettext (((void *)0), \"%s: cannot change nonblocking mode\", 5), quotearg_n_style_colon (0, shell_escape_quoting_style, name)), assume (false))" ")")... 0 : __builtin_unreachable ()))) : ((error ( 1 , (*__errno_location ()) , dcgettext (((void *)0), "%s: cannot change nonblocking mode" , 5) , quotearg_n_style_colon (0, shell_escape_quoting_style, name)), (( 0 ) ? (void) 0 : __builtin_unreachable ())))) ;
0
1184 }-
1185 else-
1186 f[i].blocking = blocking;
executed 36 times by 1 test: f[i].blocking = blocking;
Executed by:
  • tail
36
1187 }-
1188-
1189 if (!f[i].blocking)
!f[i].blockingDescription
TRUEevaluated 320 times by 1 test
Evaluated by:
  • tail
FALSEevaluated 1 time by 1 test
Evaluated by:
  • tail
1-320
1190 {-
1191 if (fstat (fd, &stats) != 0)
fstat (fd, &stats) != 0Description
TRUEnever evaluated
FALSEevaluated 320 times by 1 test
Evaluated by:
  • tail
0-320
1192 {-
1193 f[i].fd = -1;-
1194 f[i].errnum = errno;-
1195 error (0, errno, "%s", quotef (name));-
1196 close (fd); /* ignore failure */-
1197 continue;
never executed: continue;
0
1198 }-
1199-
1200 if (f[i].mode == stats.st_mode
f[i].mode == stats.st_modeDescription
TRUEevaluated 320 times by 1 test
Evaluated by:
  • tail
FALSEnever evaluated
0-320
1201 && (! S_ISREG (stats.st_mode) || f[i].size == stats.st_size)
! (((( stats.s... == (0100000))Description
TRUEnever evaluated
FALSEevaluated 320 times by 1 test
Evaluated by:
  • tail
f[i].size == stats.st_sizeDescription
TRUEevaluated 293 times by 1 test
Evaluated by:
  • tail
FALSEevaluated 27 times by 1 test
Evaluated by:
  • tail
0-320
1202 && timespec_cmp (f[i].mtime, get_stat_mtime (&stats)) == 0)
timespec_cmp (...(&stats)) == 0Description
TRUEevaluated 293 times by 1 test
Evaluated by:
  • tail
FALSEnever evaluated
0-293
1203 {-
1204 if ((max_n_unchanged_stats_between_opens
(max_n_unchang...anged_stats++)Description
TRUEevaluated 175 times by 1 test
Evaluated by:
  • tail
FALSEevaluated 118 times by 1 test
Evaluated by:
  • tail
118-175
1205 <= f[i].n_unchanged_stats++)
(max_n_unchang...anged_stats++)Description
TRUEevaluated 175 times by 1 test
Evaluated by:
  • tail
FALSEevaluated 118 times by 1 test
Evaluated by:
  • tail
118-175
1206 && follow_mode == Follow_name)
follow_mode == Follow_nameDescription
TRUEevaluated 63 times by 1 test
Evaluated by:
  • tail
FALSEevaluated 112 times by 1 test
Evaluated by:
  • tail
63-112
1207 {-
1208 recheck (&f[i], f[i].blocking);-
1209 f[i].n_unchanged_stats = 0;-
1210 }
executed 63 times by 1 test: end of block
Executed by:
  • tail
63
1211 continue;
executed 293 times by 1 test: continue;
Executed by:
  • tail
293
1212 }-
1213-
1214 /* This file has changed. Print out what we can, and-
1215 then keep looping. */-
1216-
1217 f[i].mtime = get_stat_mtime (&stats);-
1218 f[i].mode = stats.st_mode;-
1219-
1220 /* reset counter */-
1221 f[i].n_unchanged_stats = 0;-
1222-
1223 /* XXX: This is only a heuristic, as the file may have also-
1224 been truncated and written to if st_size >= size-
1225 (in which case we ignore new data <= size). */-
1226 if (S_ISREG (mode) && stats.st_size < f[i].size)
(((( mode )) &... == (0100000))Description
TRUEevaluated 27 times by 1 test
Evaluated by:
  • tail
FALSEnever evaluated
stats.st_size < f[i].sizeDescription
TRUEevaluated 4 times by 1 test
Evaluated by:
  • tail
FALSEevaluated 23 times by 1 test
Evaluated by:
  • tail
0-27
1227 {-
1228 error (0, 0, _("%s: file truncated"), quotef (name));-
1229 /* Assume the file was truncated to 0,-
1230 and therefore output all "new" data. */-
1231 xlseek (fd, 0, SEEK_SET, name);-
1232 f[i].size = 0;-
1233 }
executed 4 times by 1 test: end of block
Executed by:
  • tail
4
1234-
1235 if (i != last)
i != lastDescription
TRUEevaluated 9 times by 1 test
Evaluated by:
  • tail
FALSEevaluated 18 times by 1 test
Evaluated by:
  • tail
9-18
1236 {-
1237 if (print_headers)
print_headersDescription
TRUEevaluated 9 times by 1 test
Evaluated by:
  • tail
FALSEnever evaluated
0-9
1238 write_header (name);
executed 9 times by 1 test: write_header (name);
Executed by:
  • tail
9
1239 last = i;-
1240 }
executed 9 times by 1 test: end of block
Executed by:
  • tail
9
1241 }
executed 27 times by 1 test: end of block
Executed by:
  • tail
27
1242-
1243 /* Don't read more than st_size on networked file systems-
1244 because it was seen on glusterfs at least, that st_size-
1245 may be smaller than the data read on a _subsequent_ stat call. */-
1246 uintmax_t bytes_to_read;-
1247 if (f[i].blocking)
f[i].blockingDescription
TRUEevaluated 1 time by 1 test
Evaluated by:
  • tail
FALSEevaluated 27 times by 1 test
Evaluated by:
  • tail
1-27
1248 bytes_to_read = COPY_A_BUFFER;
executed 1 time by 1 test: bytes_to_read = ( (18446744073709551615UL) - 1);
Executed by:
  • tail
1
1249 else if (S_ISREG (mode) && f[i].remote)
(((( mode )) &... == (0100000))Description
TRUEevaluated 27 times by 1 test
Evaluated by:
  • tail
FALSEnever evaluated
f[i].remoteDescription
TRUEnever evaluated
FALSEevaluated 27 times by 1 test
Evaluated by:
  • tail
0-27
1250 bytes_to_read = stats.st_size - f[i].size;
never executed: bytes_to_read = stats.st_size - f[i].size;
0
1251 else-
1252 bytes_to_read = COPY_TO_EOF;
executed 27 times by 1 test: bytes_to_read = (18446744073709551615UL) ;
Executed by:
  • tail
27
1253-
1254 bytes_read = dump_remainder (false, name, fd, bytes_to_read);-
1255-
1256 any_input |= (bytes_read != 0);-
1257 f[i].size += bytes_read;-
1258 }
executed 28 times by 1 test: end of block
Executed by:
  • tail
28
1259-
1260 if (! any_live_files (f, n_files))
! any_live_files (f, n_files)Description
TRUEevaluated 14 times by 1 test
Evaluated by:
  • tail
FALSEevaluated 289 times by 1 test
Evaluated by:
  • tail
14-289
1261 {-
1262 error (0, 0, _("no files remaining"));-
1263 break;
executed 14 times by 1 test: break;
Executed by:
  • tail
14
1264 }-
1265-
1266 if ((!any_input || blocking) && fflush (stdout) != 0)
!any_inputDescription
TRUEevaluated 263 times by 1 test
Evaluated by:
  • tail
FALSEevaluated 26 times by 1 test
Evaluated by:
  • tail
blockingDescription
TRUEnever evaluated
FALSEevaluated 26 times by 1 test
Evaluated by:
  • tail
fflush_unlocke... stdout ) != 0Description
TRUEnever evaluated
FALSEevaluated 263 times by 1 test
Evaluated by:
  • tail
0-263
1267 die (EXIT_FAILURE, errno, _("write error"));
never executed: ((!!sizeof (struct { _Static_assert ( 1 , "verify_expr (" "1" ", " "(error (1, (*__errno_location ()), dcgettext (((void *)0), \"write error\", 5)), assume (false))" ")"); int _gl_dummy; })) ? ((error ( 1 , (*__errno_location ()) , dcgettext (((void *)0), "write error" , 5) ), (( 0 ) ? (void) 0 : __builtin_unreachable ()))) : ((error ( 1 , (*__errno_location ()) , dcgettext (((void *)0), "write error" , 5) ), (( 0 ) ? (void) 0 : __builtin_unreachable ()))));
0
1268-
1269 check_output_alive ();-
1270-
1271 /* If nothing was read, sleep and/or check for dead writers. */-
1272 if (!any_input)
!any_inputDescription
TRUEevaluated 263 times by 1 test
Evaluated by:
  • tail
FALSEevaluated 26 times by 1 test
Evaluated by:
  • tail
26-263
1273 {-
1274 if (writer_is_dead)
writer_is_deadDescription
TRUEevaluated 3 times by 1 test
Evaluated by:
  • tail
FALSEevaluated 260 times by 1 test
Evaluated by:
  • tail
3-260
1275 break;
executed 3 times by 1 test: break;
Executed by:
  • tail
3
1276-
1277 /* Once the writer is dead, read the files once more to-
1278 avoid a race condition. */-
1279 writer_is_dead = (pid != 0
pid != 0Description
TRUEevaluated 17 times by 1 test
Evaluated by:
  • tail
FALSEevaluated 243 times by 1 test
Evaluated by:
  • tail
17-243
1280 && kill (pid, 0) != 0
kill (pid, 0) != 0Description
TRUEevaluated 3 times by 1 test
Evaluated by:
  • tail
FALSEevaluated 14 times by 1 test
Evaluated by:
  • tail
3-14
1281 /* Handle the case in which you cannot send a-
1282 signal to the writer, so kill fails and sets-
1283 errno to EPERM. */-
1284 && errno != EPERM);
(*__errno_location ()) != 1Description
TRUEevaluated 3 times by 1 test
Evaluated by:
  • tail
FALSEnever evaluated
0-3
1285-
1286 if (!writer_is_dead && xnanosleep (sleep_interval))
!writer_is_deadDescription
TRUEevaluated 257 times by 1 test
Evaluated by:
  • tail
FALSEevaluated 3 times by 1 test
Evaluated by:
  • tail
xnanosleep (sleep_interval)Description
TRUEnever evaluated
FALSEevaluated 218 times by 1 test
Evaluated by:
  • tail
0-257
1287 die (EXIT_FAILURE, errno, _("cannot read realtime clock"));
never executed: ((!!sizeof (struct { _Static_assert ( 1 , "verify_expr (" "1" ", " "(error (1, (*__errno_location ()), dcgettext (((void *)0), \"cannot read realtime clock\", 5)), assume (false))" ")"); int _gl_dummy; })) ? ((error ( 1 , (*__errno_location ()) , dcgettext (((void *)0), "cannot read realtime clock" , 5) ), (( 0 ) ? (void) 0 : __builtin_unreachable ()))) : ((error ( 1 , (*__errno_location ()) , dcgettext (((void *)0), "cannot read realtime clock" , 5) ), (( 0 ) ? (void) 0 : __builtin_unreachable ()))));
0
1288-
1289 }
executed 221 times by 1 test: end of block
Executed by:
  • tail
221
1290 }
executed 247 times by 1 test: end of block
Executed by:
  • tail
247
1291}
executed 17 times by 1 test: end of block
Executed by:
  • tail
17
1292-
1293#if HAVE_INOTIFY-
1294-
1295/* Return true if any of the N_FILES files in F is remote, i.e., has-
1296 an open file descriptor and is on a network file system. */-
1297-
1298static bool-
1299any_remote_file (const struct File_spec *f, size_t n_files)-
1300{-
1301 for (size_t i = 0; i < n_files; i++)
i < n_filesDescription
TRUEevaluated 108 times by 1 test
Evaluated by:
  • tail
FALSEevaluated 94 times by 1 test
Evaluated by:
  • tail
94-108
1302 if (0 <= f[i].fd && f[i].remote)
0 <= f[i].fdDescription
TRUEevaluated 88 times by 1 test
Evaluated by:
  • tail
FALSEevaluated 20 times by 1 test
Evaluated by:
  • tail
f[i].remoteDescription
TRUEnever evaluated
FALSEevaluated 88 times by 1 test
Evaluated by:
  • tail
0-88
1303 return true;
never executed: return 1 ;
0
1304 return false;
executed 94 times by 1 test: return 0 ;
Executed by:
  • tail
94
1305}-
1306-
1307/* Return true if any of the N_FILES files in F is non remote, i.e., has-
1308 an open file descriptor and is not on a network file system. */-
1309-
1310static bool-
1311any_non_remote_file (const struct File_spec *f, size_t n_files)-
1312{-
1313 for (size_t i = 0; i < n_files; i++)
i < n_filesDescription
TRUEevaluated 97 times by 1 test
Evaluated by:
  • tail
FALSEevaluated 16 times by 1 test
Evaluated by:
  • tail
16-97
1314 if (0 <= f[i].fd && ! f[i].remote)
0 <= f[i].fdDescription
TRUEevaluated 78 times by 1 test
Evaluated by:
  • tail
FALSEevaluated 19 times by 1 test
Evaluated by:
  • tail
! f[i].remoteDescription
TRUEevaluated 78 times by 1 test
Evaluated by:
  • tail
FALSEnever evaluated
0-78
1315 return true;
executed 78 times by 1 test: return 1 ;
Executed by:
  • tail
78
1316 return false;
executed 16 times by 1 test: return 0 ;
Executed by:
  • tail
16
1317}-
1318-
1319/* Return true if any of the N_FILES files in F is a symlink.-
1320 Note we don't worry about the edge case where "-" exists,-
1321 since that will have the same consequences for inotify,-
1322 which is the only context this function is currently used. */-
1323-
1324static bool-
1325any_symlinks (const struct File_spec *f, size_t n_files)-
1326{-
1327 struct stat st;-
1328 for (size_t i = 0; i < n_files; i++)
i < n_filesDescription
TRUEevaluated 90 times by 1 test
Evaluated by:
  • tail
FALSEevaluated 77 times by 1 test
Evaluated by:
  • tail
77-90
1329 if (lstat (f[i].name, &st) == 0 && S_ISLNK (st.st_mode))
lstat (f[i].name, &st) == 0Description
TRUEevaluated 88 times by 1 test
Evaluated by:
  • tail
FALSEevaluated 2 times by 1 test
Evaluated by:
  • tail
(((( st.st_mod... == (0120000))Description
TRUEevaluated 1 time by 1 test
Evaluated by:
  • tail
FALSEevaluated 87 times by 1 test
Evaluated by:
  • tail
1-88
1330 return true;
executed 1 time by 1 test: return 1 ;
Executed by:
  • tail
1
1331 return false;
executed 77 times by 1 test: return 0 ;
Executed by:
  • tail
77
1332}-
1333-
1334/* Return true if any of the N_FILES files in F is not-
1335 a regular file or fifo. This is used to avoid adding inotify-
1336 watches on a device file for example, which inotify-
1337 will accept, but not give any events for. */-
1338-
1339static bool-
1340any_non_regular_fifo (const struct File_spec *f, size_t n_files)-
1341{-
1342 for (size_t i = 0; i < n_files; i++)
i < n_filesDescription
TRUEevaluated 89 times by 1 test
Evaluated by:
  • tail
FALSEevaluated 76 times by 1 test
Evaluated by:
  • tail
76-89
1343 if (0 <= f[i].fd && ! S_ISREG (f[i].mode) && ! S_ISFIFO (f[i].mode))
0 <= f[i].fdDescription
TRUEevaluated 87 times by 1 test
Evaluated by:
  • tail
FALSEevaluated 2 times by 1 test
Evaluated by:
  • tail
! (((( f[i].mo... == (0100000))Description
TRUEevaluated 2 times by 1 test
Evaluated by:
  • tail
FALSEevaluated 85 times by 1 test
Evaluated by:
  • tail
! (((( f[i].mo... == (0010000))Description
TRUEevaluated 1 time by 1 test
Evaluated by:
  • tail
FALSEevaluated 1 time by 1 test
Evaluated by:
  • tail
1-87
1344 return true;
executed 1 time by 1 test: return 1 ;
Executed by:
  • tail
1
1345 return false;
executed 76 times by 1 test: return 0 ;
Executed by:
  • tail
76
1346}-
1347-
1348/* Return true if any of the N_FILES files in F represents-
1349 stdin and is tailable. */-
1350-
1351static bool-
1352tailable_stdin (const struct File_spec *f, size_t n_files)-
1353{-
1354 for (size_t i = 0; i < n_files; i++)
i < n_filesDescription
TRUEevaluated 109 times by 1 test
Evaluated by:
  • tail
FALSEevaluated 94 times by 1 test
Evaluated by:
  • tail
94-109
1355 if (!f[i].ignore && STREQ (f[i].name, "-"))
never executed: __result = (((const unsigned char *) (const char *) ( f[i].name ))[3] - __s2[3]);
never executed: end of block
never executed: end of block
never executed: __result = (((const unsigned char *) (const char *) ( "-" ))[3] - __s2[3]);
never executed: end of block
executed 1 time by 1 test: end of block
Executed by:
  • tail
!f[i].ignoreDescription
TRUEevaluated 100 times by 1 test
Evaluated by:
  • tail
FALSEevaluated 9 times by 1 test
Evaluated by:
  • tail
( __extension_...)))); }) == 0)Description
TRUEevaluated 1 time by 1 test
Evaluated by:
  • tail
FALSEevaluated 99 times by 1 test
Evaluated by:
  • tail
__s1_len > 0Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s1_len > 1Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s1_len > 2Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s2_len > 0Description
TRUEevaluated 100 times by 1 test
Evaluated by:
  • tail
FALSEnever evaluated
__result == 0Description
TRUEevaluated 1 time by 1 test
Evaluated by:
  • tail
FALSEevaluated 99 times by 1 test
Evaluated by:
  • tail
__s2_len > 1Description
TRUEnever evaluated
FALSEevaluated 1 time by 1 test
Evaluated by:
  • tail
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s2_len > 2Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
0-100
1356 return true;
executed 1 time by 1 test: return 1 ;
Executed by:
  • tail
1
1357 return false;
executed 94 times by 1 test: return 0 ;
Executed by:
  • tail
94
1358}-
1359-
1360static size_t-
1361wd_hasher (const void *entry, size_t tabsize)-
1362{-
1363 const struct File_spec *spec = entry;-
1364 return spec->wd % tabsize;
executed 1462 times by 1 test: return spec->wd % tabsize;
Executed by:
  • tail
1462
1365}-
1366-
1367static bool-
1368wd_comparator (const void *e1, const void *e2)-
1369{-
1370 const struct File_spec *spec1 = e1;-
1371 const struct File_spec *spec2 = e2;-
1372 return spec1->wd == spec2->wd;
executed 304 times by 1 test: return spec1->wd == spec2->wd;
Executed by:
  • tail
304
1373}-
1374-
1375/* Output (new) data for FSPEC->fd.-
1376 PREV_FSPEC records the last File_spec for which we output. */-
1377static void-
1378check_fspec (struct File_spec *fspec, struct File_spec **prev_fspec)-
1379{-
1380 struct stat stats;-
1381 char const *name;-
1382-
1383 if (fspec->fd == -1)
fspec->fd == -1Description
TRUEevaluated 1 time by 1 test
Evaluated by:
  • tail
FALSEevaluated 398 times by 1 test
Evaluated by:
  • tail
1-398
1384 return;
executed 1 time by 1 test: return;
Executed by:
  • tail
1
1385-
1386 name = pretty_name (fspec);-
1387-
1388 if (fstat (fspec->fd, &stats) != 0)
fstat (fspec->fd, &stats) != 0Description
TRUEnever evaluated
FALSEevaluated 398 times by 1 test
Evaluated by:
  • tail
0-398
1389 {-
1390 fspec->errnum = errno;-
1391 close_fd (fspec->fd, name);-
1392 fspec->fd = -1;-
1393 return;
never executed: return;
0
1394 }-
1395-
1396 /* XXX: This is only a heuristic, as the file may have also-
1397 been truncated and written to if st_size >= size-
1398 (in which case we ignore new data <= size).-
1399 Though in the inotify case it's more likely we'll get-
1400 separate events for truncate() and write(). */-
1401 if (S_ISREG (fspec->mode) && stats.st_size < fspec->size)
(((( fspec->mo... == (0100000))Description
TRUEevaluated 397 times by 1 test
Evaluated by:
  • tail
FALSEevaluated 1 time by 1 test
Evaluated by:
  • tail
stats.st_size < fspec->sizeDescription
TRUEevaluated 2 times by 1 test
Evaluated by:
  • tail
FALSEevaluated 395 times by 1 test
Evaluated by:
  • tail
1-397
1402 {-
1403 error (0, 0, _("%s: file truncated"), quotef (name));-
1404 xlseek (fspec->fd, 0, SEEK_SET, name);-
1405 fspec->size = 0;-
1406 }
executed 2 times by 1 test: end of block
Executed by:
  • tail
2
1407 else if (S_ISREG (fspec->mode) && stats.st_size == fspec->size
(((( fspec->mo... == (0100000))Description
TRUEevaluated 395 times by 1 test
Evaluated by:
  • tail
FALSEevaluated 1 time by 1 test
Evaluated by:
  • tail
stats.st_size == fspec->sizeDescription
TRUEevaluated 334 times by 1 test
Evaluated by:
  • tail
FALSEevaluated 61 times by 1 test
Evaluated by:
  • tail
1-395
1408 && timespec_cmp (fspec->mtime, get_stat_mtime (&stats)) == 0)
timespec_cmp (...(&stats)) == 0Description
TRUEevaluated 334 times by 1 test
Evaluated by:
  • tail
FALSEnever evaluated
0-334
1409 return;
executed 334 times by 1 test: return;
Executed by:
  • tail
334
1410-
1411 bool want_header = print_headers && (fspec != *prev_fspec);
print_headersDescription
TRUEevaluated 6 times by 1 test
Evaluated by:
  • tail
FALSEevaluated 58 times by 1 test
Evaluated by:
  • tail
(fspec != *prev_fspec)Description
TRUEevaluated 3 times by 1 test
Evaluated by:
  • tail
FALSEevaluated 3 times by 1 test
Evaluated by:
  • tail
3-58
1412-
1413 uintmax_t bytes_read = dump_remainder (want_header, name, fspec->fd,-
1414 COPY_TO_EOF);-
1415 fspec->size += bytes_read;-
1416-
1417 if (bytes_read)
bytes_readDescription
TRUEevaluated 61 times by 1 test
Evaluated by:
  • tail
FALSEevaluated 3 times by 1 test
Evaluated by:
  • tail
3-61
1418 {-
1419 *prev_fspec = fspec;-
1420 if (fflush (stdout) != 0)
fflush_unlocke... stdout ) != 0Description
TRUEnever evaluated
FALSEevaluated 61 times by 1 test
Evaluated by:
  • tail
0-61
1421 die (EXIT_FAILURE, errno, _("write error"));
never executed: ((!!sizeof (struct { _Static_assert ( 1 , "verify_expr (" "1" ", " "(error (1, (*__errno_location ()), dcgettext (((void *)0), \"write error\", 5)), assume (false))" ")"); int _gl_dummy; })) ? ((error ( 1 , (*__errno_location ()) , dcgettext (((void *)0), "write error" , 5) ), (( 0 ) ? (void) 0 : __builtin_unreachable ()))) : ((error ( 1 , (*__errno_location ()) , dcgettext (((void *)0), "write error" , 5) ), (( 0 ) ? (void) 0 : __builtin_unreachable ()))));
0
1422 }
executed 61 times by 1 test: end of block
Executed by:
  • tail
61
1423}
executed 64 times by 1 test: end of block
Executed by:
  • tail
64
1424-
1425/* Attempt to tail N_FILES files forever, or until killed.-
1426 Check modifications using the inotify events system.-
1427 Return false on error, or true to revert to polling. */-
1428static bool-
1429tail_forever_inotify (int wd, struct File_spec *f, size_t n_files,-
1430 double sleep_interval)-
1431{-
1432# if TAIL_TEST_SLEEP-
1433 /* Delay between open() and inotify_add_watch()-
1434 to help trigger different cases. */-
1435 xnanosleep (1000000);-
1436# endif-
1437 unsigned int max_realloc = 3;-
1438-
1439 /* Map an inotify watch descriptor to the name of the file it's watching. */-
1440 Hash_table *wd_to_name;-
1441-
1442 bool found_watchable_file = false;-
1443 bool tailed_but_unwatchable = false;-
1444 bool found_unwatchable_dir = false;-
1445 bool no_inotify_resources = false;-
1446 bool writer_is_dead = false;-
1447 struct File_spec *prev_fspec;-
1448 size_t evlen = 0;-
1449 char *evbuf;-
1450 size_t evbuf_off = 0;-
1451 size_t len = 0;-
1452-
1453 wd_to_name = hash_initialize (n_files, NULL, wd_hasher, wd_comparator, NULL);-
1454 if (! wd_to_name)
! wd_to_nameDescription
TRUEnever evaluated
FALSEevaluated 75 times by 1 test
Evaluated by:
  • tail
0-75
1455 xalloc_die ();
never executed: xalloc_die ();
0
1456-
1457 /* The events mask used with inotify on files (not directories). */-
1458 uint32_t inotify_wd_mask = IN_MODIFY;-
1459 /* TODO: Perhaps monitor these events in Follow_descriptor mode also,-
1460 to tag reported file names with "deleted", "moved" etc. */-
1461 if (follow_mode == Follow_name)
follow_mode == Follow_nameDescription
TRUEevaluated 59 times by 1 test
Evaluated by:
  • tail
FALSEevaluated 16 times by 1 test
Evaluated by:
  • tail
16-59
1462 inotify_wd_mask |= (IN_ATTRIB | IN_DELETE_SELF | IN_MOVE_SELF);
executed 59 times by 1 test: inotify_wd_mask |= ( 0x00000004 | 0x00000400 | 0x00000800 );
Executed by:
  • tail
59
1463-
1464 /* Add an inotify watch for each watched file. If -F is specified then watch-
1465 its parent directory too, in this way when they re-appear we can add them-
1466 again to the watch list. */-
1467 size_t i;-
1468 for (i = 0; i < n_files; i++)
i < n_filesDescription
TRUEevaluated 86 times by 1 test
Evaluated by:
  • tail
FALSEevaluated 75 times by 1 test
Evaluated by:
  • tail
75-86
1469 {-
1470 if (!f[i].ignore)
!f[i].ignoreDescription
TRUEevaluated 86 times by 1 test
Evaluated by:
  • tail
FALSEnever evaluated
0-86
1471 {-
1472 size_t fnlen = strlen (f[i].name);-
1473 if (evlen < fnlen)
evlen < fnlenDescription
TRUEevaluated 77 times by 1 test
Evaluated by:
  • tail
FALSEevaluated 9 times by 1 test
Evaluated by:
  • tail
9-77
1474 evlen = fnlen;
executed 77 times by 1 test: evlen = fnlen;
Executed by:
  • tail
77
1475-
1476 f[i].wd = -1;-
1477-
1478 if (follow_mode == Follow_name)
follow_mode == Follow_nameDescription
TRUEevaluated 70 times by 1 test
Evaluated by:
  • tail
FALSEevaluated 16 times by 1 test
Evaluated by:
  • tail
16-70
1479 {-
1480 size_t dirlen = dir_len (f[i].name);-
1481 char prev = f[i].name[dirlen];-
1482 f[i].basename_start = last_component (f[i].name) - f[i].name;-
1483-
1484 f[i].name[dirlen] = '\0';-
1485-
1486 /* It's fine to add the same directory more than once.-
1487 In that case the same watch descriptor is returned. */-
1488 f[i].parent_wd = inotify_add_watch (wd, dirlen ? f[i].name : ".",-
1489 (IN_CREATE | IN_DELETE-
1490 | IN_MOVED_TO | IN_ATTRIB-
1491 | IN_DELETE_SELF));-
1492-
1493 f[i].name[dirlen] = prev;-
1494-
1495 if (f[i].parent_wd < 0)
f[i].parent_wd < 0Description
TRUEnever evaluated
FALSEevaluated 70 times by 1 test
Evaluated by:
  • tail
0-70
1496 {-
1497 if (errno != ENOSPC) /* suppress confusing error. */
(*__errno_location ()) != 28Description
TRUEnever evaluated
FALSEnever evaluated
0
1498 error (0, errno, _("cannot watch parent directory of %s"),
never executed: error (0, (*__errno_location ()) , dcgettext (((void *)0), "cannot watch parent directory of %s" , 5) , quotearg_style (shell_escape_always_quoting_style, f[i].name));
0
1499 quoteaf (f[i].name));
never executed: error (0, (*__errno_location ()) , dcgettext (((void *)0), "cannot watch parent directory of %s" , 5) , quotearg_style (shell_escape_always_quoting_style, f[i].name));
0
1500 else-
1501 error (0, 0, _("inotify resources exhausted"));
never executed: error (0, 0, dcgettext (((void *)0), "inotify resources exhausted" , 5) );
0
1502 found_unwatchable_dir = true;-
1503 /* We revert to polling below. Note invalid uses-
1504 of the inotify API will still be diagnosed. */-
1505 break;
never executed: break;
0
1506 }-
1507 }
executed 70 times by 1 test: end of block
Executed by:
  • tail
70
1508-
1509 f[i].wd = inotify_add_watch (wd, f[i].name, inotify_wd_mask);-
1510-
1511 if (f[i].wd < 0)
f[i].wd < 0Description
TRUEevaluated 1 time by 1 test
Evaluated by:
  • tail
FALSEevaluated 85 times by 1 test
Evaluated by:
  • tail
1-85
1512 {-
1513 if (f[i].fd != -1) /* already tailed. */
f[i].fd != -1Description
TRUEnever evaluated
FALSEevaluated 1 time by 1 test
Evaluated by:
  • tail
0-1
1514 tailed_but_unwatchable = true;
never executed: tailed_but_unwatchable = 1 ;
0
1515 if (errno == ENOSPC || errno == ENOMEM)
(*__errno_location ()) == 28Description
TRUEnever evaluated
FALSEevaluated 1 time by 1 test
Evaluated by:
  • tail
(*__errno_location ()) == 12Description
TRUEnever evaluated
FALSEevaluated 1 time by 1 test
Evaluated by:
  • tail
0-1
1516 {-
1517 no_inotify_resources = true;-
1518 error (0, 0, _("inotify resources exhausted"));-
1519 break;
never executed: break;
0
1520 }-
1521 else if (errno != f[i].errnum)
(*__errno_loca...!= f[i].errnumDescription
TRUEnever evaluated
FALSEevaluated 1 time by 1 test
Evaluated by:
  • tail
0-1
1522 error (0, errno, _("cannot watch %s"), quoteaf (f[i].name));
never executed: error (0, (*__errno_location ()) , dcgettext (((void *)0), "cannot watch %s" , 5) , quotearg_style (shell_escape_always_quoting_style, f[i].name));
0
1523 continue;
executed 1 time by 1 test: continue;
Executed by:
  • tail
1
1524 }-
1525-
1526 if (hash_insert (wd_to_name, &(f[i])) == NULL)
hash_insert (w...== ((void *)0)Description
TRUEnever evaluated
FALSEevaluated 85 times by 1 test
Evaluated by:
  • tail
0-85
1527 xalloc_die ();
never executed: xalloc_die ();
0
1528-
1529 found_watchable_file = true;-
1530 }
executed 85 times by 1 test: end of block
Executed by:
  • tail
85
1531 }
executed 85 times by 1 test: end of block
Executed by:
  • tail
85
1532-
1533 /* Linux kernel 2.6.24 at least has a bug where eventually, ENOSPC is always-
1534 returned by inotify_add_watch. In any case we should revert to polling-
1535 when there are no inotify resources. Also a specified directory may not-
1536 be currently present or accessible, so revert to polling. Also an already-
1537 tailed but unwatchable due rename/unlink race, should also revert. */-
1538 if (no_inotify_resources || found_unwatchable_dir
no_inotify_resourcesDescription
TRUEnever evaluated
FALSEevaluated 75 times by 1 test
Evaluated by:
  • tail
found_unwatchable_dirDescription
TRUEnever evaluated
FALSEevaluated 75 times by 1 test
Evaluated by:
  • tail
0-75
1539 || (follow_mode == Follow_descriptor && tailed_but_unwatchable))
follow_mode ==...low_descriptorDescription
TRUEevaluated 16 times by 1 test
Evaluated by:
  • tail
FALSEevaluated 59 times by 1 test
Evaluated by:
  • tail
tailed_but_unwatchableDescription
TRUEnever evaluated
FALSEevaluated 16 times by 1 test
Evaluated by:
  • tail
0-59
1540 {-
1541 hash_free (wd_to_name);-
1542-
1543 errno = 0;-
1544 return true;
never executed: return 1 ;
0
1545 }-
1546 if (follow_mode == Follow_descriptor && !found_watchable_file)
follow_mode ==...low_descriptorDescription
TRUEevaluated 16 times by 1 test
Evaluated by:
  • tail
FALSEevaluated 59 times by 1 test
Evaluated by:
  • tail
!found_watchable_fileDescription
TRUEnever evaluated
FALSEevaluated 16 times by 1 test
Evaluated by:
  • tail
0-59
1547 return false;
never executed: return 0 ;
0
1548-
1549 prev_fspec = &(f[n_files - 1]);-
1550-
1551 /* Check files again. New files or data can be available since last time we-
1552 checked and before they are watched by inotify. */-
1553 for (i = 0; i < n_files; i++)
i < n_filesDescription
TRUEevaluated 86 times by 1 test
Evaluated by:
  • tail
FALSEevaluated 75 times by 1 test
Evaluated by:
  • tail
75-86
1554 {-
1555 if (! f[i].ignore)
! f[i].ignoreDescription
TRUEevaluated 86 times by 1 test
Evaluated by:
  • tail
FALSEnever evaluated
0-86
1556 {-
1557 /* check for new files. */-
1558 if (follow_mode == Follow_name)
follow_mode == Follow_nameDescription
TRUEevaluated 70 times by 1 test
Evaluated by:
  • tail
FALSEevaluated 16 times by 1 test
Evaluated by:
  • tail
16-70
1559 recheck (&(f[i]), false);
executed 70 times by 1 test: recheck (&(f[i]), 0 );
Executed by:
  • tail
70
1560 else if (f[i].fd != -1)
f[i].fd != -1Description
TRUEevaluated 16 times by 1 test
Evaluated by:
  • tail
FALSEnever evaluated
0-16
1561 {-
1562 /* If the file was replaced in the small window since we tailed,-
1563 then assume the watch is on the wrong item (different to-
1564 that we've already produced output for), and so revert to-
1565 polling the original descriptor. */-
1566 struct stat stats;-
1567-
1568 if (stat (f[i].name, &stats) == 0
stat (f[i].name, &stats) == 0Description
TRUEevaluated 16 times by 1 test
Evaluated by:
  • tail
FALSEnever evaluated
0-16
1569 && (f[i].dev != stats.st_dev || f[i].ino != stats.st_ino))
f[i].dev != stats.st_devDescription
TRUEnever evaluated
FALSEevaluated 16 times by 1 test
Evaluated by:
  • tail
f[i].ino != stats.st_inoDescription
TRUEnever evaluated
FALSEevaluated 16 times by 1 test
Evaluated by:
  • tail
0-16
1570 {-
1571 error (0, errno, _("%s was replaced"),-
1572 quoteaf (pretty_name (&(f[i]))));-
1573 hash_free (wd_to_name);-
1574-
1575 errno = 0;-
1576 return true;
never executed: return 1 ;
0
1577 }-
1578 }
executed 16 times by 1 test: end of block
Executed by:
  • tail
16
1579-
1580 /* check for new data. */-
1581 check_fspec (&f[i], &prev_fspec);-
1582 }
executed 86 times by 1 test: end of block
Executed by:
  • tail
86
1583 }
executed 86 times by 1 test: end of block
Executed by:
  • tail
86
1584-
1585 evlen += sizeof (struct inotify_event) + 1;-
1586 evbuf = xmalloc (evlen);-
1587-
1588 /* Wait for inotify events and handle them. Events on directories-
1589 ensure that watched files can be re-added when following by name.-
1590 This loop blocks on the 'safe_read' call until a new event is notified.-
1591 But when --pid=P is specified, tail usually waits via the select. */-
1592 while (1)-
1593 {-
1594 struct File_spec *fspec;-
1595 struct inotify_event *ev;-
1596 void *void_ev;-
1597-
1598 /* When following by name without --retry, and the last file has-
1599 been unlinked or renamed-away, diagnose it and return. */-
1600 if (follow_mode == Follow_name
follow_mode == Follow_nameDescription
TRUEevaluated 1383 times by 1 test
Evaluated by:
  • tail
FALSEevaluated 19 times by 1 test
Evaluated by:
  • tail
19-1383
1601 && ! reopen_inaccessible_files
! reopen_inaccessible_filesDescription
TRUEevaluated 7 times by 1 test
Evaluated by:
  • tail
FALSEevaluated 1376 times by 1 test
Evaluated by:
  • tail
7-1376
1602 && hash_get_n_entries (wd_to_name) == 0)
hash_get_n_ent..._to_name) == 0Description
TRUEnever evaluated
FALSEevaluated 7 times by 1 test
Evaluated by:
  • tail
0-7
1603 {-
1604 error (0, 0, _("no files remaining"));-
1605 return false;
never executed: return 0 ;
0
1606 }-
1607-
1608 /* When watching a PID, ensure that a read from WD will not block-
1609 indefinitely. */-
1610 while (len <= evbuf_off)
len <= evbuf_offDescription
TRUEevaluated 1668071 times by 1 test
Evaluated by:
  • tail
FALSEevaluated 46 times by 1 test
Evaluated by:
  • tail
46-1668071
1611 {-
1612 struct timeval delay; /* how long to wait for file changes. */-
1613-
1614 if (pid)
pidDescription
TRUEevaluated 42 times by 1 test
Evaluated by:
  • tail
FALSEevaluated 1668029 times by 1 test
Evaluated by:
  • tail
42-1668029
1615 {-
1616 if (writer_is_dead)
writer_is_deadDescription
TRUEevaluated 4 times by 1 test
Evaluated by:
  • tail
FALSEevaluated 38 times by 1 test
Evaluated by:
  • tail
4-38
1617 exit (EXIT_SUCCESS);
executed 4 times by 1 test: exit ( 0 );
Executed by:
  • tail
4
1618-
1619 writer_is_dead = (kill (pid, 0) != 0 && errno != EPERM);
kill (pid, 0) != 0Description
TRUEevaluated 4 times by 1 test
Evaluated by:
  • tail
FALSEevaluated 34 times by 1 test
Evaluated by:
  • tail
(*__errno_location ()) != 1Description
TRUEevaluated 4 times by 1 test
Evaluated by:
  • tail
FALSEnever evaluated
0-34
1620-
1621 if (writer_is_dead)
writer_is_deadDescription
TRUEevaluated 4 times by 1 test
Evaluated by:
  • tail
FALSEevaluated 34 times by 1 test
Evaluated by:
  • tail
4-34
1622 delay.tv_sec = delay.tv_usec = 0;
executed 4 times by 1 test: delay.tv_sec = delay.tv_usec = 0;
Executed by:
  • tail
4
1623 else-
1624 {-
1625 delay.tv_sec = (time_t) sleep_interval;-
1626 delay.tv_usec = 1000000 * (sleep_interval - delay.tv_sec);-
1627 }
executed 34 times by 1 test: end of block
Executed by:
  • tail
34
1628 }-
1629-
1630 fd_set rfd;-
1631 FD_ZERO (&rfd);-
1632 FD_SET (wd, &rfd);-
1633 if (monitor_output)
monitor_outputDescription
TRUEevaluated 1666683 times by 1 test
Evaluated by:
  • tail
FALSEevaluated 1384 times by 1 test
Evaluated by:
  • tail
1384-1666683
1634 FD_SET (STDOUT_FILENO, &rfd);
executed 1666683 times by 1 test: ((void) ((( &rfd )->fds_bits)[__extension__ ({ long int __d = (1); (__builtin_constant_p (__d) ? (0 <= __d && __d < 1024 ? (__d / (8 * (int) sizeof (__fd_mask))) : __fdelt_warn (__d)) : __fdelt_chk (__d)); })] |= ((__fd_mask) (1UL << ((1) % (8 * (int) sizeof (__fd_mask))))))) ;
Executed by:
  • tail
1666683
1635-
1636 int file_change = select (MAX (wd, STDOUT_FILENO) + 1,-
1637 &rfd, NULL, NULL, pid ? &delay: NULL);-
1638-
1639 if (file_change == 0)
file_change == 0Description
TRUEevaluated 33 times by 1 test
Evaluated by:
  • tail
FALSEevaluated 1667965 times by 1 test
Evaluated by:
  • tail
33-1667965
1640 continue;
executed 33 times by 1 test: continue;
Executed by:
  • tail
33
1641 else if (file_change == -1)
file_change == -1Description
TRUEnever evaluated
FALSEevaluated 1667965 times by 1 test
Evaluated by:
  • tail
0-1667965
1642 die (EXIT_FAILURE, errno,
never executed: ((!!sizeof (struct { _Static_assert ( 1 , "verify_expr (" "1" ", " "(error (1, (*__errno_location ()), dcgettext (((void *)0), \"error waiting for inotify and output events\", 5)), assume (false))" ")"); int _gl_dummy; })) ? ((error ( 1 , (*__errno_locati...or inotify and output events" , 5) ), (( 0 ) ? (void) 0 : __builtin_unreachable ()))) : ((error ( 1 , (*__errno_location ()) , dcgettext (((void *)0), "error waiting for inotify and output events" , 5) ), (( 0 ) ? (void) 0 : __builtin_unreachable ())))) ;
0
1643 _("error waiting for inotify and output events"));
never executed: ((!!sizeof (struct { _Static_assert ( 1 , "verify_expr (" "1" ", " "(error (1, (*__errno_location ()), dcgettext (((void *)0), \"error waiting for inotify and output events\", 5)), assume (false))" ")"); int _gl_dummy; })) ? ((error ( 1 , (*__errno_locati...or inotify and output events" , 5) ), (( 0 ) ? (void) 0 : __builtin_unreachable ()))) : ((error ( 1 , (*__errno_location ()) , dcgettext (((void *)0), "error waiting for inotify and output events" , 5) ), (( 0 ) ? (void) 0 : __builtin_unreachable ())))) ;
0
1644 else if (FD_ISSET (STDOUT_FILENO, &rfd))
(((( &rfd )->f...sk)))))) != 0)Description
TRUEevaluated 1666683 times by 1 test
Evaluated by:
  • tail
FALSEevaluated 1282 times by 1 test
Evaluated by:
  • tail
1282-1666683
1645 {-
1646 /* readable event on STDOUT is equivalent to POLLERR,-
1647 and implies an error on output like broken pipe. */-
1648 raise (SIGPIPE);-
1649 }
executed 1666682 times by 1 test: end of block
Executed by:
  • tail
1666682
1650 else-
1651 break;
executed 1282 times by 1 test: break;
Executed by:
  • tail
1282
1652 }-
1653-
1654 if (len <= evbuf_off)
len <= evbuf_offDescription
TRUEevaluated 1282 times by 1 test
Evaluated by:
  • tail
FALSEevaluated 46 times by 1 test
Evaluated by:
  • tail
46-1282
1655 {-
1656 len = safe_read (wd, evbuf, evlen);-
1657 evbuf_off = 0;-
1658-
1659 /* For kernels prior to 2.6.21, read returns 0 when the buffer-
1660 is too small. */-
1661 if ((len == 0 || (len == SAFE_READ_ERROR && errno == EINVAL))
len == 0Description
TRUEnever evaluated
FALSEevaluated 1282 times by 1 test
Evaluated by:
  • tail
len == ((size_t) -1)Description
TRUEevaluated 57 times by 1 test
Evaluated by:
  • tail
FALSEevaluated 1225 times by 1 test
Evaluated by:
  • tail
(*__errno_location ()) == 22Description
TRUEevaluated 57 times by 1 test
Evaluated by:
  • tail
FALSEnever evaluated
0-1282
1662 && max_realloc--)
max_realloc--Description
TRUEevaluated 57 times by 1 test
Evaluated by:
  • tail
FALSEnever evaluated
0-57
1663 {-
1664 len = 0;-
1665 evlen *= 2;-
1666 evbuf = xrealloc (evbuf, evlen);-
1667 continue;
executed 57 times by 1 test: continue;
Executed by:
  • tail
57
1668 }-
1669-
1670 if (len == 0 || len == SAFE_READ_ERROR)
len == 0Description
TRUEnever evaluated
FALSEevaluated 1225 times by 1 test
Evaluated by:
  • tail
len == ((size_t) -1)Description
TRUEnever evaluated
FALSEevaluated 1225 times by 1 test
Evaluated by:
  • tail
0-1225
1671 die (EXIT_FAILURE, errno, _("error reading inotify event"));
never executed: ((!!sizeof (struct { _Static_assert ( 1 , "verify_expr (" "1" ", " "(error (1, (*__errno_location ()), dcgettext (((void *)0), \"error reading inotify event\", 5)), assume (false))" ")"); int _gl_dummy; })) ? ((error ( 1 , (*__errno_location ()) , dcgettext (((void *)0), "error reading inotify event" , 5) ), (( 0 ) ? (void) 0 : __builtin_unreachable ()))) : ((error ( 1 , (*__errno_location ()) , dcgettext (((void *)0), "error reading inotify event" , 5) ), (( 0 ) ? (void) 0 : __builtin_unreachable ()))));
0
1672 }
executed 1225 times by 1 test: end of block
Executed by:
  • tail
1225
1673-
1674 void_ev = evbuf + evbuf_off;-
1675 ev = void_ev;-
1676 evbuf_off += sizeof (*ev) + ev->len;-
1677-
1678 /* If a directory is deleted, IN_DELETE_SELF is emitted-
1679 with ev->name of length 0.-
1680 We need to catch it, otherwise it would wait forever,-
1681 as wd for directory becomes inactive. Revert to polling now. */-
1682 if ((ev->mask & IN_DELETE_SELF) && ! ev->len)
(ev->mask & 0x00000400 )Description
TRUEevaluated 3 times by 1 test
Evaluated by:
  • tail
FALSEevaluated 1268 times by 1 test
Evaluated by:
  • tail
! ev->lenDescription
TRUEevaluated 3 times by 1 test
Evaluated by:
  • tail
FALSEnever evaluated
0-1268
1683 {-
1684 for (i = 0; i < n_files; i++)
i < n_filesDescription
TRUEevaluated 4 times by 1 test
Evaluated by:
  • tail
FALSEevaluated 2 times by 1 test
Evaluated by:
  • tail
2-4
1685 {-
1686 if (ev->wd == f[i].parent_wd)
ev->wd == f[i].parent_wdDescription
TRUEevaluated 1 time by 1 test
Evaluated by:
  • tail
FALSEevaluated 3 times by 1 test
Evaluated by:
  • tail
1-3
1687 {-
1688 hash_free (wd_to_name);-
1689 error (0, 0,-
1690 _("directory containing watched file was removed"));-
1691 errno = 0; /* we've already diagnosed enough errno detail. */-
1692 return true;
executed 1 time by 1 test: return 1 ;
Executed by:
  • tail
1
1693 }-
1694 }
executed 3 times by 1 test: end of block
Executed by:
  • tail
3
1695 }
executed 2 times by 1 test: end of block
Executed by:
  • tail
2
1696-
1697 if (ev->len) /* event on ev->name in watched directory. */
ev->lenDescription
TRUEevaluated 661 times by 1 test
Evaluated by:
  • tail
FALSEevaluated 609 times by 1 test
Evaluated by:
  • tail
609-661
1698 {-
1699 size_t j;-
1700 for (j = 0; j < n_files; j++)
j < n_filesDescription
TRUEevaluated 673 times by 1 test
Evaluated by:
  • tail
FALSEevaluated 203 times by 1 test
Evaluated by:
  • tail
203-673
1701 {-
1702 /* With N=hundreds of frequently-changing files, this O(N^2)-
1703 process might be a problem. FIXME: use a hash table? */-
1704 if (f[j].parent_wd == ev->wd
f[j].parent_wd == ev->wdDescription
TRUEevaluated 673 times by 1 test
Evaluated by:
  • tail
FALSEnever evaluated
0-673
1705 && STREQ (ev->name, f[j].name + f[j].basename_start))
never executed: __result = (((const unsigned char *) (const char *) ( ev->name ))[3] - __s2[3]);
never executed: end of block
never executed: end of block
never executed: __result = (((const unsigned char *) (const char *) ( f[j].name + f[j].basename_start ))[3] - __s2[3]);
never executed: end of block
never executed: end of block
( __extension_...)))); }) == 0)Description
TRUEevaluated 458 times by 1 test
Evaluated by:
  • tail
FALSEevaluated 215 times by 1 test
Evaluated by:
  • tail
__s1_len > 0Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s1_len > 1Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s1_len > 2Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s2_len > 0Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s2_len > 1Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s2_len > 2Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
0-458
1706 break;
executed 458 times by 1 test: break;
Executed by:
  • tail
458
1707 }
executed 215 times by 1 test: end of block
Executed by:
  • tail
215
1708-
1709 /* It is not a watched file. */-
1710 if (j == n_files)
j == n_filesDescription
TRUEevaluated 203 times by 1 test
Evaluated by:
  • tail
FALSEevaluated 458 times by 1 test
Evaluated by:
  • tail
203-458
1711 continue;
executed 203 times by 1 test: continue;
Executed by:
  • tail
203
1712-
1713 fspec = &(f[j]);-
1714-
1715 int new_wd = -1;-
1716 bool deleting = !! (ev->mask & IN_DELETE);-
1717-
1718 if (! deleting)
! deletingDescription
TRUEevaluated 456 times by 1 test
Evaluated by:
  • tail
FALSEevaluated 2 times by 1 test
Evaluated by:
  • tail
2-456
1719 {-
1720 /* Adding the same inode again will look up any existing wd. */-
1721 new_wd = inotify_add_watch (wd, f[j].name, inotify_wd_mask);-
1722 }
executed 456 times by 1 test: end of block
Executed by:
  • tail
456
1723-
1724 if (! deleting && new_wd < 0)
! deletingDescription
TRUEevaluated 456 times by 1 test
Evaluated by:
  • tail
FALSEevaluated 2 times by 1 test
Evaluated by:
  • tail
new_wd < 0Description
TRUEnever evaluated
FALSEevaluated 456 times by 1 test
Evaluated by:
  • tail
0-456
1725 {-
1726 if (errno == ENOSPC || errno == ENOMEM)
(*__errno_location ()) == 28Description
TRUEnever evaluated
FALSEnever evaluated
(*__errno_location ()) == 12Description
TRUEnever evaluated
FALSEnever evaluated
0
1727 {-
1728 error (0, 0, _("inotify resources exhausted"));-
1729 hash_free (wd_to_name);-
1730 errno = 0;-
1731 return true; /* revert to polling. */
never executed: return 1 ;
0
1732 }-
1733 else-
1734 {-
1735 /* Can get ENOENT for a dangling symlink for example. */-
1736 error (0, errno, _("cannot watch %s"), quoteaf (f[j].name));-
1737 }
never executed: end of block
0
1738 /* We'll continue below after removing the existing watch. */-
1739 }-
1740-
1741 /* This will be false if only attributes of file change. */-
1742 bool new_watch;-
1743 new_watch = (! deleting) && (fspec->wd < 0 || new_wd != fspec->wd);
(! deleting)Description
TRUEevaluated 456 times by 1 test
Evaluated by:
  • tail
FALSEevaluated 2 times by 1 test
Evaluated by:
  • tail
fspec->wd < 0Description
TRUEevaluated 2 times by 1 test
Evaluated by:
  • tail
FALSEevaluated 454 times by 1 test
Evaluated by:
  • tail
new_wd != fspec->wdDescription
TRUEevaluated 254 times by 1 test
Evaluated by:
  • tail
FALSEevaluated 200 times by 1 test
Evaluated by:
  • tail
2-456
1744-
1745 if (new_watch)
new_watchDescription
TRUEevaluated 256 times by 1 test
Evaluated by:
  • tail
FALSEevaluated 202 times by 1 test
Evaluated by:
  • tail
202-256
1746 {-
1747 if (0 <= fspec->wd)
0 <= fspec->wdDescription
TRUEevaluated 254 times by 1 test
Evaluated by:
  • tail
FALSEevaluated 2 times by 1 test
Evaluated by:
  • tail
2-254
1748 {-
1749 inotify_rm_watch (wd, fspec->wd);-
1750 hash_delete (wd_to_name, fspec);-
1751 }
executed 254 times by 1 test: end of block
Executed by:
  • tail
254
1752-
1753 fspec->wd = new_wd;-
1754-
1755 if (new_wd == -1)
new_wd == -1Description
TRUEnever evaluated
FALSEevaluated 256 times by 1 test
Evaluated by:
  • tail
0-256
1756 continue;
never executed: continue;
0
1757-
1758 /* If the file was moved then inotify will use the source file wd-
1759 for the destination file. Make sure the key is not present in-
1760 the table. */-
1761 struct File_spec *prev = hash_delete (wd_to_name, fspec);-
1762 if (prev && prev != fspec)
prevDescription
TRUEevaluated 1 time by 1 test
Evaluated by:
  • tail
FALSEevaluated 255 times by 1 test
Evaluated by:
  • tail
prev != fspecDescription
TRUEevaluated 1 time by 1 test
Evaluated by:
  • tail
FALSEnever evaluated
0-255
1763 {-
1764 if (follow_mode == Follow_name)
follow_mode == Follow_nameDescription
TRUEevaluated 1 time by 1 test
Evaluated by:
  • tail
FALSEnever evaluated
0-1
1765 recheck (prev, false);
executed 1 time by 1 test: recheck (prev, 0 );
Executed by:
  • tail
1
1766 prev->wd = -1;-
1767 close_fd (prev->fd, pretty_name (prev));-
1768 }
executed 1 time by 1 test: end of block
Executed by:
  • tail
1
1769-
1770 if (hash_insert (wd_to_name, fspec) == NULL)
hash_insert (w...== ((void *)0)Description
TRUEnever evaluated
FALSEevaluated 256 times by 1 test
Evaluated by:
  • tail
0-256
1771 xalloc_die ();
never executed: xalloc_die ();
0
1772 }
executed 256 times by 1 test: end of block
Executed by:
  • tail
256
1773-
1774 if (follow_mode == Follow_name)
follow_mode == Follow_nameDescription
TRUEevaluated 458 times by 1 test
Evaluated by:
  • tail
FALSEnever evaluated
0-458
1775 recheck (fspec, false);
executed 458 times by 1 test: recheck (fspec, 0 );
Executed by:
  • tail
458
1776 }
executed 458 times by 1 test: end of block
Executed by:
  • tail
458
1777 else-
1778 {-
1779 struct File_spec key;-
1780 key.wd = ev->wd;-
1781 fspec = hash_lookup (wd_to_name, &key);-
1782 }
executed 609 times by 1 test: end of block
Executed by:
  • tail
609
1783-
1784 if (! fspec)
! fspecDescription
TRUEevaluated 306 times by 1 test
Evaluated by:
  • tail
FALSEevaluated 761 times by 1 test
Evaluated by:
  • tail
306-761
1785 continue;
executed 306 times by 1 test: continue;
Executed by:
  • tail
306
1786-
1787 if (ev->mask & (IN_ATTRIB | IN_DELETE | IN_DELETE_SELF | IN_MOVE_SELF))
ev->mask & ( 0...| 0x00000800 )Description
TRUEevaluated 448 times by 1 test
Evaluated by:
  • tail
FALSEevaluated 313 times by 1 test
Evaluated by:
  • tail
313-448
1788 {-
1789 /* Note for IN_MOVE_SELF (the file we're watching has-
1790 been clobbered via a rename) we leave the watch-
1791 in place since it may still be part of the set-
1792 of watched names. */-
1793 if (ev->mask & IN_DELETE_SELF)
ev->mask & 0x00000400Description
TRUEevaluated 2 times by 1 test
Evaluated by:
  • tail
FALSEevaluated 446 times by 1 test
Evaluated by:
  • tail
2-446
1794 {-
1795 inotify_rm_watch (wd, fspec->wd);-
1796 hash_delete (wd_to_name, fspec);-
1797 }
executed 2 times by 1 test: end of block
Executed by:
  • tail
2
1798-
1799 /* Note we get IN_ATTRIB for unlink() as st_nlink decrements.-
1800 The usual path is a close() done in recheck() triggers-
1801 an IN_DELETE_SELF event as the inode is removed.-
1802 However sometimes open() will succeed as even though-
1803 st_nlink is decremented, the dentry (cache) is not updated.-
1804 Thus we depend on the IN_DELETE event on the directory-
1805 to trigger processing for the removed file. */-
1806-
1807 recheck (fspec, false);-
1808-
1809 continue;
executed 448 times by 1 test: continue;
Executed by:
  • tail
448
1810 }-
1811 check_fspec (fspec, &prev_fspec);-
1812 }
executed 313 times by 1 test: end of block
Executed by:
  • tail
313
1813}
never executed: end of block
0
1814#endif-
1815-
1816/* Output the last N_BYTES bytes of file FILENAME open for reading in FD.-
1817 Return true if successful. */-
1818-
1819static bool-
1820tail_bytes (const char *pretty_filename, int fd, uintmax_t n_bytes,-
1821 uintmax_t *read_pos)-
1822{-
1823 struct stat stats;-
1824-
1825 if (fstat (fd, &stats))
fstat (fd, &stats)Description
TRUEnever evaluated
FALSEevaluated 47 times by 1 test
Evaluated by:
  • tail
0-47
1826 {-
1827 error (0, errno, _("cannot fstat %s"), quoteaf (pretty_filename));-
1828 return false;
never executed: return 0 ;
0
1829 }-
1830-
1831 if (from_start)
from_startDescription
TRUEevaluated 9 times by 1 test
Evaluated by:
  • tail
FALSEevaluated 38 times by 1 test
Evaluated by:
  • tail
9-38
1832 {-
1833 if (! presume_input_pipe && n_bytes <= OFF_T_MAX
! presume_input_pipeDescription
TRUEevaluated 9 times by 1 test
Evaluated by:
  • tail
FALSEnever evaluated
n_bytes <= ((o... 1) * 2 + 1)))Description
TRUEevaluated 9 times by 1 test
Evaluated by:
  • tail
FALSEnever evaluated
0-9
1834 && ((S_ISREG (stats.st_mode)
(((( stats.st_... == (0100000))Description
TRUEevaluated 6 times by 1 test
Evaluated by:
  • tail
FALSEevaluated 3 times by 1 test
Evaluated by:
  • tail
3-6
1835 && xlseek (fd, n_bytes, SEEK_CUR, pretty_filename) >= 0)
xlseek (fd, n_...filename) >= 0Description
TRUEevaluated 6 times by 1 test
Evaluated by:
  • tail
FALSEnever evaluated
0-6
1836 || lseek (fd, n_bytes, SEEK_CUR) != -1))
lseek (fd, n_bytes, 1 ) != -1Description
TRUEnever evaluated
FALSEevaluated 3 times by 1 test
Evaluated by:
  • tail
0-3
1837 *read_pos += n_bytes;
executed 6 times by 1 test: *read_pos += n_bytes;
Executed by:
  • tail
6
1838 else-
1839 {-
1840 int t = start_bytes (pretty_filename, fd, n_bytes, read_pos);-
1841 if (t)
tDescription
TRUEevaluated 1 time by 1 test
Evaluated by:
  • tail
FALSEevaluated 2 times by 1 test
Evaluated by:
  • tail
1-2
1842 return t < 0;
executed 1 time by 1 test: return t < 0;
Executed by:
  • tail
1
1843 }
executed 2 times by 1 test: end of block
Executed by:
  • tail
2
1844 n_bytes = COPY_TO_EOF;-
1845 }
executed 8 times by 1 test: end of block
Executed by:
  • tail
8
1846 else-
1847 {-
1848 off_t end_pos = -1;-
1849 off_t current_pos = -1;-
1850-
1851 if (! presume_input_pipe && n_bytes <= OFF_T_MAX)
! presume_input_pipeDescription
TRUEevaluated 38 times by 1 test
Evaluated by:
  • tail
FALSEnever evaluated
n_bytes <= ((o... 1) * 2 + 1)))Description
TRUEevaluated 38 times by 1 test
Evaluated by:
  • tail
FALSEnever evaluated
0-38
1852 {-
1853 if (usable_st_size (&stats))
usable_st_size (&stats)Description
TRUEevaluated 25 times by 1 test
Evaluated by:
  • tail
FALSEevaluated 13 times by 1 test
Evaluated by:
  • tail
13-25
1854 end_pos = stats.st_size;
executed 25 times by 1 test: end_pos = stats.st_size;
Executed by:
  • tail
25
1855 else if ((current_pos = lseek (fd, -n_bytes, SEEK_END)) != -1)
(current_pos =...es, 2 )) != -1Description
TRUEnever evaluated
FALSEevaluated 13 times by 1 test
Evaluated by:
  • tail
0-13
1856 end_pos = current_pos + n_bytes;
never executed: end_pos = current_pos + n_bytes;
0
1857 }
executed 38 times by 1 test: end of block
Executed by:
  • tail
38
1858 if (end_pos <= (off_t) ST_BLKSIZE (stats))
end_pos <= (of...lksize : 512 )Description
TRUEevaluated 35 times by 1 test
Evaluated by:
  • tail
FALSEevaluated 3 times by 1 test
Evaluated by:
  • tail
3-35
1859 return pipe_bytes (pretty_filename, fd, n_bytes, read_pos);
executed 35 times by 1 test: return pipe_bytes (pretty_filename, fd, n_bytes, read_pos);
Executed by:
  • tail
35
1860 if (current_pos == -1)
current_pos == -1Description
TRUEevaluated 3 times by 1 test
Evaluated by:
  • tail
FALSEnever evaluated
0-3
1861 current_pos = xlseek (fd, 0, SEEK_CUR, pretty_filename);
executed 3 times by 1 test: current_pos = xlseek (fd, 0, 1 , pretty_filename);
Executed by:
  • tail
3
1862 if (current_pos < end_pos)
current_pos < end_posDescription
TRUEevaluated 3 times by 1 test
Evaluated by:
  • tail
FALSEnever evaluated
0-3
1863 {-
1864 off_t bytes_remaining = end_pos - current_pos;-
1865-
1866 if (n_bytes < bytes_remaining)
n_bytes < bytes_remainingDescription
TRUEevaluated 3 times by 1 test
Evaluated by:
  • tail
FALSEnever evaluated
0-3
1867 {-
1868 current_pos = end_pos - n_bytes;-
1869 xlseek (fd, current_pos, SEEK_SET, pretty_filename);-
1870 }
executed 3 times by 1 test: end of block
Executed by:
  • tail
3
1871 }
executed 3 times by 1 test: end of block
Executed by:
  • tail
3
1872 *read_pos = current_pos;-
1873 }
executed 3 times by 1 test: end of block
Executed by:
  • tail
3
1874-
1875 *read_pos += dump_remainder (false, pretty_filename, fd, n_bytes);-
1876 return true;
executed 11 times by 1 test: return 1 ;
Executed by:
  • tail
11
1877}-
1878-
1879/* Output the last N_LINES lines of file FILENAME open for reading in FD.-
1880 Return true if successful. */-
1881-
1882static bool-
1883tail_lines (const char *pretty_filename, int fd, uintmax_t n_lines,-
1884 uintmax_t *read_pos)-
1885{-
1886 struct stat stats;-
1887-
1888 if (fstat (fd, &stats))
fstat (fd, &stats)Description
TRUEevaluated 1 time by 1 test
Evaluated by:
  • tail
FALSEevaluated 197 times by 1 test
Evaluated by:
  • tail
1-197
1889 {-
1890 error (0, errno, _("cannot fstat %s"), quoteaf (pretty_filename));-
1891 return false;
executed 1 time by 1 test: return 0 ;
Executed by:
  • tail
1
1892 }-
1893-
1894 if (from_start)
from_startDescription
TRUEevaluated 26 times by 1 test
Evaluated by:
  • tail
FALSEevaluated 171 times by 1 test
Evaluated by:
  • tail
26-171
1895 {-
1896 int t = start_lines (pretty_filename, fd, n_lines, read_pos);-
1897 if (t)
tDescription
TRUEnever evaluated
FALSEevaluated 26 times by 1 test
Evaluated by:
  • tail
0-26
1898 return t < 0;
never executed: return t < 0;
0
1899 *read_pos += dump_remainder (false, pretty_filename, fd, COPY_TO_EOF);-
1900 }
executed 26 times by 1 test: end of block
Executed by:
  • tail
26
1901 else-
1902 {-
1903 off_t start_pos = -1;-
1904 off_t end_pos;-
1905-
1906 /* Use file_lines only if FD refers to a regular file for-
1907 which lseek (... SEEK_END) works. */-
1908 if ( ! presume_input_pipe
! presume_input_pipeDescription
TRUEevaluated 171 times by 1 test
Evaluated by:
  • tail
FALSEnever evaluated
0-171
1909 && S_ISREG (stats.st_mode)
(((( stats.st_... == (0100000))Description
TRUEevaluated 146 times by 1 test
Evaluated by:
  • tail
FALSEevaluated 25 times by 1 test
Evaluated by:
  • tail
25-146
1910