Line data Source code
1 : /* head -- output first part of file(s)
2 : Copyright (C) 89, 90, 91, 1995-2006 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 <http://www.gnu.org/licenses/>. */
16 :
17 : /* Options: (see usage)
18 : Reads from standard input if no files are given or when a filename of
19 : ``-'' is encountered.
20 : By default, filename headers are printed only if more than one file
21 : is given.
22 : By default, prints the first 10 lines (head -n 10).
23 :
24 : David MacKenzie <djm@gnu.ai.mit.edu> */
25 :
26 : #include <config.h>
27 :
28 : #include <stdio.h>
29 : #include <getopt.h>
30 : #include <sys/types.h>
31 :
32 : #include "system.h"
33 :
34 : #include "error.h"
35 : #include "full-write.h"
36 : #include "full-read.h"
37 : #include "inttostr.h"
38 : #include "quote.h"
39 : #include "safe-read.h"
40 : #include "xstrtol.h"
41 :
42 : /* The official name of this program (e.g., no `g' prefix). */
43 : #define PROGRAM_NAME "head"
44 :
45 : #define AUTHORS "David MacKenzie", "Jim Meyering"
46 :
47 : /* Number of lines/chars/blocks to head. */
48 : #define DEFAULT_NUMBER 10
49 :
50 : /* Useful only when eliding tail bytes or lines.
51 : If true, skip the is-regular-file test used to determine whether
52 : to use the lseek optimization. Instead, use the more general (and
53 : more expensive) code unconditionally. Intended solely for testing. */
54 : static bool presume_input_pipe;
55 :
56 : /* If true, print filename headers. */
57 : static bool print_headers;
58 :
59 : /* When to print the filename banners. */
60 : enum header_mode
61 : {
62 : multiple_files, always, never
63 : };
64 :
65 : /* The name this program was run with. */
66 : char *program_name;
67 :
68 : /* Have we ever read standard input? */
69 : static bool have_read_stdin;
70 :
71 : enum Copy_fd_status
72 : {
73 : COPY_FD_OK = 0,
74 : COPY_FD_READ_ERROR,
75 : COPY_FD_WRITE_ERROR,
76 : COPY_FD_UNEXPECTED_EOF
77 : };
78 :
79 : /* For long options that have no equivalent short option, use a
80 : non-character as a pseudo short option, starting with CHAR_MAX + 1. */
81 : enum
82 : {
83 : PRESUME_INPUT_PIPE_OPTION = CHAR_MAX + 1
84 : };
85 :
86 : static struct option const long_options[] =
87 : {
88 : {"bytes", required_argument, NULL, 'c'},
89 : {"lines", required_argument, NULL, 'n'},
90 : {"-presume-input-pipe", no_argument, NULL,
91 : PRESUME_INPUT_PIPE_OPTION}, /* do not document */
92 : {"quiet", no_argument, NULL, 'q'},
93 : {"silent", no_argument, NULL, 'q'},
94 : {"verbose", no_argument, NULL, 'v'},
95 : {GETOPT_HELP_OPTION_DECL},
96 : {GETOPT_VERSION_OPTION_DECL},
97 : {NULL, 0, NULL, 0}
98 : };
99 :
100 : void
101 13 : usage (int status)
102 : {
103 13 : if (status != EXIT_SUCCESS)
104 12 : fprintf (stderr, _("Try `%s --help' for more information.\n"),
105 : program_name);
106 : else
107 : {
108 1 : printf (_("\
109 : Usage: %s [OPTION]... [FILE]...\n\
110 : "),
111 : program_name);
112 1 : fputs (_("\
113 : Print the first 10 lines of each FILE to standard output.\n\
114 : With more than one FILE, precede each with a header giving the file name.\n\
115 : With no FILE, or when FILE is -, read standard input.\n\
116 : \n\
117 : "), stdout);
118 1 : fputs (_("\
119 : Mandatory arguments to long options are mandatory for short options too.\n\
120 : "), stdout);
121 1 : fputs (_("\
122 : -c, --bytes=[-]N print the first N bytes of each file;\n\
123 : with the leading `-', print all but the last\n\
124 : N bytes of each file\n\
125 : -n, --lines=[-]N print the first N lines instead of the first 10;\n\
126 : with the leading `-', print all but the last\n\
127 : N lines of each file\n\
128 : "), stdout);
129 1 : fputs (_("\
130 : -q, --quiet, --silent never print headers giving file names\n\
131 : -v, --verbose always print headers giving file names\n\
132 : "), stdout);
133 1 : fputs (HELP_OPTION_DESCRIPTION, stdout);
134 1 : fputs (VERSION_OPTION_DESCRIPTION, stdout);
135 1 : fputs (_("\
136 : \n\
137 : N may have a multiplier suffix:\n\
138 : b 512, kB 1000, K 1024, MB 1000*1000, M 1024*1024,\n\
139 : GB 1000*1000*1000, G 1024*1024*1024, and so on for T, P, E, Z, Y.\n\
140 : "), stdout);
141 1 : emit_bug_reporting_address ();
142 : }
143 13 : exit (status);
144 : }
145 :
146 : static void
147 0 : diagnose_copy_fd_failure (enum Copy_fd_status err, char const *filename)
148 : {
149 0 : switch (err)
150 : {
151 0 : case COPY_FD_READ_ERROR:
152 0 : error (0, errno, _("error reading %s"), quote (filename));
153 0 : break;
154 0 : case COPY_FD_WRITE_ERROR:
155 0 : error (0, errno, _("error writing %s"), quote (filename));
156 0 : break;
157 0 : case COPY_FD_UNEXPECTED_EOF:
158 0 : error (0, errno, _("%s: file has shrunk too much"), quote (filename));
159 0 : break;
160 0 : default:
161 0 : abort ();
162 : }
163 0 : }
164 :
165 : static void
166 32 : write_header (const char *filename)
167 : {
168 : static bool first_file = true;
169 :
170 32 : printf ("%s==> %s <==\n", (first_file ? "" : "\n"), filename);
171 32 : first_file = false;
172 32 : }
173 :
174 : /* Copy no more than N_BYTES from file descriptor SRC_FD to O_STREAM.
175 : Return an appropriate indication of success or failure. */
176 :
177 : static enum Copy_fd_status
178 1 : copy_fd (int src_fd, FILE *o_stream, uintmax_t n_bytes)
179 : {
180 : char buf[BUFSIZ];
181 1 : const size_t buf_size = sizeof (buf);
182 :
183 : /* Copy the file contents. */
184 3 : while (0 < n_bytes)
185 : {
186 1 : size_t n_to_read = MIN (buf_size, n_bytes);
187 1 : size_t n_read = safe_read (src_fd, buf, n_to_read);
188 1 : if (n_read == SAFE_READ_ERROR)
189 0 : return COPY_FD_READ_ERROR;
190 :
191 1 : n_bytes -= n_read;
192 :
193 1 : if (n_read == 0 && n_bytes != 0)
194 0 : return COPY_FD_UNEXPECTED_EOF;
195 :
196 1 : if (fwrite (buf, 1, n_read, o_stream) < n_read)
197 0 : return COPY_FD_WRITE_ERROR;
198 : }
199 :
200 1 : return COPY_FD_OK;
201 : }
202 :
203 : /* Print all but the last N_ELIDE lines from the input available via
204 : the non-seekable file descriptor FD. Return true upon success.
205 : Give a diagnostic and return false upon error. */
206 : static bool
207 5 : elide_tail_bytes_pipe (const char *filename, int fd, uintmax_t n_elide_0)
208 : {
209 5 : size_t n_elide = n_elide_0;
210 :
211 : #ifndef HEAD_TAIL_PIPE_READ_BUFSIZE
212 : # define HEAD_TAIL_PIPE_READ_BUFSIZE BUFSIZ
213 : #endif
214 : #define READ_BUFSIZE HEAD_TAIL_PIPE_READ_BUFSIZE
215 :
216 : /* If we're eliding no more than this many bytes, then it's ok to allocate
217 : more memory in order to use a more time-efficient algorithm.
218 : FIXME: use a fraction of available memory instead, as in sort.
219 : FIXME: is this even worthwhile? */
220 : #ifndef HEAD_TAIL_PIPE_BYTECOUNT_THRESHOLD
221 : # define HEAD_TAIL_PIPE_BYTECOUNT_THRESHOLD 1024 * 1024
222 : #endif
223 :
224 : #if HEAD_TAIL_PIPE_BYTECOUNT_THRESHOLD < 2 * READ_BUFSIZE
225 : "HEAD_TAIL_PIPE_BYTECOUNT_THRESHOLD must be at least 2 * READ_BUFSIZE"
226 : #endif
227 :
228 : if (SIZE_MAX < n_elide_0 + READ_BUFSIZE)
229 : {
230 : char umax_buf[INT_BUFSIZE_BOUND (uintmax_t)];
231 : error (EXIT_FAILURE, 0, _("%s: number of bytes is too large"),
232 : umaxtostr (n_elide_0, umax_buf));
233 : }
234 :
235 : /* Two cases to consider...
236 : 1) n_elide is small enough that we can afford to double-buffer:
237 : allocate 2 * (READ_BUFSIZE + n_elide) bytes
238 : 2) n_elide is too big for that, so we allocate only
239 : (READ_BUFSIZE + n_elide) bytes
240 :
241 : FIXME: profile, to see if double-buffering is worthwhile
242 :
243 : CAUTION: do not fail (out of memory) when asked to elide
244 : a ridiculous amount, but when given only a small input. */
245 :
246 5 : if (n_elide <= HEAD_TAIL_PIPE_BYTECOUNT_THRESHOLD)
247 : {
248 3 : bool ok = true;
249 3 : bool first = true;
250 3 : bool eof = false;
251 3 : size_t n_to_read = READ_BUFSIZE + n_elide;
252 : bool i;
253 : char *b[2];
254 3 : b[0] = xnmalloc (2, n_to_read);
255 3 : b[1] = b[0] + n_to_read;
256 :
257 6 : for (i = false; ! eof ; i = !i)
258 : {
259 3 : size_t n_read = full_read (fd, b[i], n_to_read);
260 3 : size_t delta = 0;
261 3 : if (n_read < n_to_read)
262 : {
263 3 : if (errno != 0)
264 : {
265 0 : error (0, errno, _("error reading %s"), quote (filename));
266 0 : ok = false;
267 0 : break;
268 : }
269 :
270 : /* reached EOF */
271 3 : if (n_read <= n_elide)
272 : {
273 0 : if (first)
274 : {
275 : /* The input is no larger than the number of bytes
276 : to elide. So there's nothing to output, and
277 : we're done. */
278 : }
279 : else
280 : {
281 0 : delta = n_elide - n_read;
282 : }
283 : }
284 3 : eof = true;
285 : }
286 :
287 : /* Output any (but maybe just part of the) elided data from
288 : the previous round. */
289 3 : if ( ! first)
290 : {
291 : /* Don't bother checking for errors here.
292 : If there's a failure, the test of the following
293 : fwrite or in close_stdout will catch it. */
294 0 : fwrite (b[!i] + READ_BUFSIZE, 1, n_elide - delta, stdout);
295 : }
296 3 : first = false;
297 :
298 3 : if (n_elide < n_read
299 3 : && fwrite (b[i], 1, n_read - n_elide, stdout) < n_read - n_elide)
300 : {
301 0 : error (0, errno, _("write error"));
302 0 : ok = false;
303 0 : break;
304 : }
305 : }
306 :
307 3 : free (b[0]);
308 3 : return ok;
309 : }
310 : else
311 : {
312 : /* Read blocks of size READ_BUFSIZE, until we've read at least n_elide
313 : bytes. Then, for each new buffer we read, also write an old one. */
314 :
315 2 : bool ok = true;
316 2 : bool eof = false;
317 : size_t n_read;
318 : bool buffered_enough;
319 : size_t i, i_next;
320 : char **b;
321 : /* Round n_elide up to a multiple of READ_BUFSIZE. */
322 2 : size_t rem = READ_BUFSIZE - (n_elide % READ_BUFSIZE);
323 2 : size_t n_elide_round = n_elide + rem;
324 2 : size_t n_bufs = n_elide_round / READ_BUFSIZE + 1;
325 2 : b = xcalloc (n_bufs, sizeof *b);
326 :
327 2 : buffered_enough = false;
328 4 : for (i = 0, i_next = 1; !eof; i = i_next, i_next = (i_next + 1) % n_bufs)
329 : {
330 2 : if (b[i] == NULL)
331 2 : b[i] = xmalloc (READ_BUFSIZE);
332 2 : n_read = full_read (fd, b[i], READ_BUFSIZE);
333 2 : if (n_read < READ_BUFSIZE)
334 : {
335 2 : if (errno != 0)
336 : {
337 0 : error (0, errno, _("error reading %s"), quote (filename));
338 0 : ok = false;
339 0 : goto free_mem;
340 : }
341 2 : eof = true;
342 : }
343 :
344 2 : if (i + 1 == n_bufs)
345 0 : buffered_enough = true;
346 :
347 2 : if (buffered_enough)
348 : {
349 0 : if (fwrite (b[i_next], 1, n_read, stdout) < n_read)
350 : {
351 0 : error (0, errno, _("write error"));
352 0 : ok = false;
353 0 : goto free_mem;
354 : }
355 : }
356 : }
357 :
358 : /* Output any remainder: rem bytes from b[i] + n_read. */
359 2 : if (rem)
360 : {
361 2 : if (buffered_enough)
362 : {
363 0 : size_t n_bytes_left_in_b_i = READ_BUFSIZE - n_read;
364 0 : if (rem < n_bytes_left_in_b_i)
365 : {
366 0 : fwrite (b[i] + n_read, 1, rem, stdout);
367 : }
368 : else
369 : {
370 0 : fwrite (b[i] + n_read, 1, n_bytes_left_in_b_i, stdout);
371 0 : fwrite (b[i_next], 1, rem - n_bytes_left_in_b_i, stdout);
372 : }
373 : }
374 2 : else if (i + 1 == n_bufs)
375 : {
376 : /* This happens when n_elide < file_size < n_elide_round.
377 :
378 : |READ_BUF.|
379 : | | rem |
380 : |---------!---------!---------!---------|
381 : |---- n_elide ---------|
382 : | | x |
383 : | |y |
384 : |---- file size -----------|
385 : | |n_read|
386 : |---- n_elide_round ----------|
387 : */
388 0 : size_t y = READ_BUFSIZE - rem;
389 0 : size_t x = n_read - y;
390 0 : fwrite (b[i_next], 1, x, stdout);
391 : }
392 : }
393 :
394 4 : free_mem:;
395 554 : for (i = 0; i < n_bufs; i++)
396 552 : free (b[i]);
397 2 : free (b);
398 :
399 2 : return ok;
400 : }
401 : }
402 :
403 : /* Print all but the last N_ELIDE lines from the input available
404 : via file descriptor FD. Return true upon success.
405 : Give a diagnostic and return false upon error. */
406 :
407 : /* NOTE: if the input file shrinks by more than N_ELIDE bytes between
408 : the length determination and the actual reading, then head fails. */
409 :
410 : static bool
411 9 : elide_tail_bytes_file (const char *filename, int fd, uintmax_t n_elide)
412 : {
413 : struct stat stats;
414 :
415 9 : if (presume_input_pipe || fstat (fd, &stats) || ! S_ISREG (stats.st_mode))
416 : {
417 5 : return elide_tail_bytes_pipe (filename, fd, n_elide);
418 : }
419 : else
420 : {
421 : off_t current_pos, end_pos;
422 : uintmax_t bytes_remaining;
423 : off_t diff;
424 : enum Copy_fd_status err;
425 :
426 4 : if ((current_pos = lseek (fd, (off_t) 0, SEEK_CUR)) == -1
427 4 : || (end_pos = lseek (fd, (off_t) 0, SEEK_END)) == -1)
428 : {
429 0 : error (0, errno, _("cannot lseek %s"), quote (filename));
430 0 : return false;
431 : }
432 :
433 : /* Be careful here. The current position may actually be
434 : beyond the end of the file. */
435 4 : bytes_remaining = (diff = end_pos - current_pos) < 0 ? 0 : diff;
436 :
437 4 : if (bytes_remaining <= n_elide)
438 3 : return true;
439 :
440 : /* Seek back to `current' position, then copy the required
441 : number of bytes from fd. */
442 1 : if (lseek (fd, (off_t) 0, current_pos) == -1)
443 : {
444 0 : error (0, errno, _("%s: cannot lseek back to original position"),
445 : quote (filename));
446 0 : return false;
447 : }
448 :
449 1 : err = copy_fd (fd, stdout, bytes_remaining - n_elide);
450 1 : if (err == COPY_FD_OK)
451 1 : return true;
452 :
453 0 : diagnose_copy_fd_failure (err, filename);
454 0 : return false;
455 : }
456 : }
457 :
458 : /* Print all but the last N_ELIDE lines from the input stream
459 : open for reading via file descriptor FD.
460 : Buffer the specified number of lines as a linked list of LBUFFERs,
461 : adding them as needed. Return true if successful. */
462 :
463 : static bool
464 1 : elide_tail_lines_pipe (const char *filename, int fd, uintmax_t n_elide)
465 : {
466 : struct linebuffer
467 : {
468 : char buffer[BUFSIZ];
469 : size_t nbytes;
470 : size_t nlines;
471 : struct linebuffer *next;
472 : };
473 : typedef struct linebuffer LBUFFER;
474 : LBUFFER *first, *last, *tmp;
475 1 : size_t total_lines = 0; /* Total number of newlines in all buffers. */
476 1 : bool ok = true;
477 : size_t n_read; /* Size in bytes of most recent read */
478 :
479 1 : first = last = xmalloc (sizeof (LBUFFER));
480 1 : first->nbytes = first->nlines = 0;
481 1 : first->next = NULL;
482 1 : tmp = xmalloc (sizeof (LBUFFER));
483 :
484 : /* Always read into a fresh buffer.
485 : Read, (producing no output) until we've accumulated at least
486 : n_elide newlines, or until EOF, whichever comes first. */
487 : while (1)
488 : {
489 1 : n_read = safe_read (fd, tmp->buffer, BUFSIZ);
490 1 : if (n_read == 0 || n_read == SAFE_READ_ERROR)
491 : break;
492 0 : tmp->nbytes = n_read;
493 0 : tmp->nlines = 0;
494 0 : tmp->next = NULL;
495 :
496 : /* Count the number of newlines just read. */
497 : {
498 0 : char const *buffer_end = tmp->buffer + n_read;
499 0 : char const *p = tmp->buffer;
500 0 : while ((p = memchr (p, '\n', buffer_end - p)))
501 : {
502 0 : ++p;
503 0 : ++tmp->nlines;
504 : }
505 : }
506 0 : total_lines += tmp->nlines;
507 :
508 : /* If there is enough room in the last buffer read, just append the new
509 : one to it. This is because when reading from a pipe, `n_read' can
510 : often be very small. */
511 0 : if (tmp->nbytes + last->nbytes < BUFSIZ)
512 : {
513 0 : memcpy (&last->buffer[last->nbytes], tmp->buffer, tmp->nbytes);
514 0 : last->nbytes += tmp->nbytes;
515 0 : last->nlines += tmp->nlines;
516 : }
517 : else
518 : {
519 : /* If there's not enough room, link the new buffer onto the end of
520 : the list, then either free up the oldest buffer for the next
521 : read if that would leave enough lines, or else malloc a new one.
522 : Some compaction mechanism is possible but probably not
523 : worthwhile. */
524 0 : last = last->next = tmp;
525 0 : if (n_elide < total_lines - first->nlines)
526 : {
527 0 : fwrite (first->buffer, 1, first->nbytes, stdout);
528 0 : tmp = first;
529 0 : total_lines -= first->nlines;
530 0 : first = first->next;
531 : }
532 : else
533 0 : tmp = xmalloc (sizeof (LBUFFER));
534 : }
535 : }
536 :
537 1 : free (tmp);
538 :
539 1 : if (n_read == SAFE_READ_ERROR)
540 : {
541 0 : error (0, errno, _("error reading %s"), quote (filename));
542 0 : ok = false;
543 0 : goto free_lbuffers;
544 : }
545 :
546 : /* If we read any bytes at all, count the incomplete line
547 : on files that don't end with a newline. */
548 1 : if (last->nbytes && last->buffer[last->nbytes - 1] != '\n')
549 : {
550 0 : ++last->nlines;
551 0 : ++total_lines;
552 : }
553 :
554 1 : for (tmp = first; n_elide < total_lines - tmp->nlines; tmp = tmp->next)
555 : {
556 0 : fwrite (tmp->buffer, 1, tmp->nbytes, stdout);
557 0 : total_lines -= tmp->nlines;
558 : }
559 :
560 : /* Print the first `total_lines - n_elide' lines of tmp->buffer. */
561 1 : if (n_elide < total_lines)
562 : {
563 0 : size_t n = total_lines - n_elide;
564 0 : char const *buffer_end = tmp->buffer + tmp->nbytes;
565 0 : char const *p = tmp->buffer;
566 0 : while (n && (p = memchr (p, '\n', buffer_end - p)))
567 : {
568 0 : ++p;
569 0 : ++tmp->nlines;
570 0 : --n;
571 : }
572 0 : fwrite (tmp->buffer, 1, p - tmp->buffer, stdout);
573 : }
574 :
575 2 : free_lbuffers:
576 3 : while (first)
577 : {
578 1 : tmp = first->next;
579 1 : free (first);
580 1 : first = tmp;
581 : }
582 1 : return ok;
583 : }
584 :
585 : /* Output all but the last N_LINES lines of the input stream defined by
586 : FD, START_POS, and END_POS.
587 : START_POS is the starting position of the read pointer for the file
588 : associated with FD (may be nonzero).
589 : END_POS is the file offset of EOF (one larger than offset of last byte).
590 : Return true upon success.
591 : Give a diagnostic and return false upon error.
592 :
593 : NOTE: this code is very similar to that of tail.c's file_lines function.
594 : Unfortunately, factoring out some common core looks like it'd result
595 : in a less efficient implementation or a messy interface. */
596 : static bool
597 5 : elide_tail_lines_seekable (const char *pretty_filename, int fd,
598 : uintmax_t n_lines,
599 : off_t start_pos, off_t end_pos)
600 : {
601 : char buffer[BUFSIZ];
602 : size_t bytes_read;
603 5 : off_t pos = end_pos;
604 :
605 : /* Set `bytes_read' to the size of the last, probably partial, buffer;
606 : 0 < `bytes_read' <= `BUFSIZ'. */
607 5 : bytes_read = (pos - start_pos) % BUFSIZ;
608 5 : if (bytes_read == 0)
609 0 : bytes_read = BUFSIZ;
610 : /* Make `pos' a multiple of `BUFSIZ' (0 if the file is short), so that all
611 : reads will be on block boundaries, which might increase efficiency. */
612 5 : pos -= bytes_read;
613 5 : if (lseek (fd, pos, SEEK_SET) < 0)
614 : {
615 : char offset_buf[INT_BUFSIZE_BOUND (off_t)];
616 0 : error (0, errno, _("%s: cannot seek to offset %s"),
617 : pretty_filename, offtostr (pos, offset_buf));
618 0 : return false;
619 : }
620 5 : bytes_read = safe_read (fd, buffer, bytes_read);
621 5 : if (bytes_read == SAFE_READ_ERROR)
622 : {
623 1 : error (0, errno, _("error reading %s"), quote (pretty_filename));
624 1 : return false;
625 : }
626 :
627 : /* Count the incomplete line on files that don't end with a newline. */
628 4 : if (bytes_read && buffer[bytes_read - 1] != '\n')
629 1 : --n_lines;
630 :
631 : while (1)
632 0 : {
633 : /* Scan backward, counting the newlines in this bufferfull. */
634 :
635 4 : size_t n = bytes_read;
636 9 : while (n)
637 : {
638 : char const *nl;
639 5 : nl = memrchr (buffer, '\n', n);
640 5 : if (nl == NULL)
641 0 : break;
642 5 : n = nl - buffer;
643 5 : if (n_lines-- == 0)
644 : {
645 : /* Found it. */
646 : /* If necessary, restore the file pointer and copy
647 : input to output up to position, POS. */
648 4 : if (start_pos < pos)
649 : {
650 : enum Copy_fd_status err;
651 0 : if (lseek (fd, start_pos, SEEK_SET) < 0)
652 : {
653 : /* Failed to reposition file pointer. */
654 0 : error (0, errno,
655 : "%s: unable to restore file pointer to initial offset",
656 : quote (pretty_filename));
657 0 : return false;
658 : }
659 :
660 0 : err = copy_fd (fd, stdout, pos - start_pos);
661 0 : if (err != COPY_FD_OK)
662 : {
663 0 : diagnose_copy_fd_failure (err, pretty_filename);
664 0 : return false;
665 : }
666 : }
667 :
668 : /* Output the initial portion of the buffer
669 : in which we found the desired newline byte.
670 : Don't bother testing for failure for such a small amount.
671 : Any failure will be detected upon close. */
672 4 : fwrite (buffer, 1, n + 1, stdout);
673 4 : return true;
674 : }
675 : }
676 :
677 : /* Not enough newlines in that bufferfull. */
678 0 : if (pos == start_pos)
679 : {
680 : /* Not enough lines in the file. */
681 0 : return true;
682 : }
683 0 : pos -= BUFSIZ;
684 0 : if (lseek (fd, pos, SEEK_SET) < 0)
685 : {
686 : char offset_buf[INT_BUFSIZE_BOUND (off_t)];
687 0 : error (0, errno, _("%s: cannot seek to offset %s"),
688 : pretty_filename, offtostr (pos, offset_buf));
689 0 : return false;
690 : }
691 :
692 0 : bytes_read = safe_read (fd, buffer, BUFSIZ);
693 0 : if (bytes_read == SAFE_READ_ERROR)
694 : {
695 0 : error (0, errno, _("error reading %s"), quote (pretty_filename));
696 0 : return false;
697 : }
698 :
699 : /* FIXME: is this dead code?
700 : Consider the test, pos == start_pos, above. */
701 0 : if (bytes_read == 0)
702 0 : return true;
703 : }
704 : }
705 :
706 : /* Print all but the last N_ELIDE lines from the input available
707 : via file descriptor FD. Return true upon success.
708 : Give a diagnostic and return nonzero upon error. */
709 :
710 : static bool
711 6 : elide_tail_lines_file (const char *filename, int fd, uintmax_t n_elide)
712 : {
713 6 : if (!presume_input_pipe)
714 : {
715 : /* Find the offset, OFF, of the Nth newline from the end,
716 : but not counting the last byte of the file.
717 : If found, write from current position to OFF, inclusive.
718 : Otherwise, just return true. */
719 :
720 6 : off_t start_pos = lseek (fd, (off_t) 0, SEEK_CUR);
721 6 : off_t end_pos = lseek (fd, (off_t) 0, SEEK_END);
722 6 : if (0 <= start_pos && start_pos < end_pos)
723 : {
724 : /* If the file is empty, we're done. */
725 5 : if (end_pos == 0)
726 0 : return true;
727 :
728 5 : return elide_tail_lines_seekable (filename, fd, n_elide,
729 : start_pos, end_pos);
730 : }
731 :
732 : /* lseek failed or the end offset precedes start.
733 : Fall through. */
734 : }
735 :
736 1 : return elide_tail_lines_pipe (filename, fd, n_elide);
737 : }
738 :
739 : static bool
740 13 : head_bytes (const char *filename, int fd, uintmax_t bytes_to_write)
741 : {
742 : char buffer[BUFSIZ];
743 13 : size_t bytes_to_read = BUFSIZ;
744 :
745 32 : while (bytes_to_write)
746 : {
747 : size_t bytes_read;
748 10 : if (bytes_to_write < bytes_to_read)
749 6 : bytes_to_read = bytes_to_write;
750 10 : bytes_read = safe_read (fd, buffer, bytes_to_read);
751 10 : if (bytes_read == SAFE_READ_ERROR)
752 : {
753 0 : error (0, errno, _("error reading %s"), quote (filename));
754 0 : return false;
755 : }
756 10 : if (bytes_read == 0)
757 4 : break;
758 6 : if (fwrite (buffer, 1, bytes_read, stdout) < bytes_read)
759 0 : error (EXIT_FAILURE, errno, _("write error"));
760 6 : bytes_to_write -= bytes_read;
761 : }
762 13 : return true;
763 : }
764 :
765 : static bool
766 43 : head_lines (const char *filename, int fd, uintmax_t lines_to_write)
767 : {
768 : char buffer[BUFSIZ];
769 :
770 102 : while (lines_to_write)
771 : {
772 35 : size_t bytes_read = safe_read (fd, buffer, BUFSIZ);
773 35 : size_t bytes_to_write = 0;
774 :
775 35 : if (bytes_read == SAFE_READ_ERROR)
776 : {
777 3 : error (0, errno, _("error reading %s"), quote (filename));
778 3 : return false;
779 : }
780 32 : if (bytes_read == 0)
781 16 : break;
782 136 : while (bytes_to_write < bytes_read)
783 107 : if (buffer[bytes_to_write++] == '\n' && --lines_to_write == 0)
784 : {
785 3 : off_t n_bytes_past_EOL = bytes_read - bytes_to_write;
786 : /* If we have read more data than that on the specified number
787 : of lines, try to seek back to the position we would have
788 : gotten to had we been reading one byte at a time. */
789 3 : if (lseek (fd, -n_bytes_past_EOL, SEEK_CUR) < 0)
790 : {
791 0 : int e = errno;
792 : struct stat st;
793 0 : if (fstat (fd, &st) != 0 || S_ISREG (st.st_mode))
794 0 : error (0, e, _("cannot reposition file pointer for %s"),
795 : quote (filename));
796 : }
797 3 : break;
798 : }
799 16 : if (fwrite (buffer, 1, bytes_to_write, stdout) < bytes_to_write)
800 0 : error (EXIT_FAILURE, errno, _("write error"));
801 : }
802 40 : return true;
803 : }
804 :
805 : static bool
806 71 : head (const char *filename, int fd, uintmax_t n_units, bool count_lines,
807 : bool elide_from_end)
808 : {
809 71 : if (print_headers)
810 32 : write_header (filename);
811 :
812 71 : if (elide_from_end)
813 : {
814 15 : if (count_lines)
815 : {
816 6 : return elide_tail_lines_file (filename, fd, n_units);
817 : }
818 : else
819 : {
820 9 : return elide_tail_bytes_file (filename, fd, n_units);
821 : }
822 : }
823 56 : if (count_lines)
824 43 : return head_lines (filename, fd, n_units);
825 : else
826 13 : return head_bytes (filename, fd, n_units);
827 : }
828 :
829 : static bool
830 85 : head_file (const char *filename, uintmax_t n_units, bool count_lines,
831 : bool elide_from_end)
832 : {
833 : int fd;
834 : bool ok;
835 85 : bool is_stdin = STREQ (filename, "-");
836 :
837 85 : if (is_stdin)
838 : {
839 64 : have_read_stdin = true;
840 64 : fd = STDIN_FILENO;
841 64 : filename = _("standard input");
842 : if (O_BINARY && ! isatty (STDIN_FILENO))
843 : freopen (NULL, "rb", stdin);
844 : }
845 : else
846 : {
847 21 : fd = open (filename, O_RDONLY | O_BINARY);
848 21 : if (fd < 0)
849 : {
850 14 : error (0, errno, _("cannot open %s for reading"), quote (filename));
851 14 : return false;
852 : }
853 : }
854 :
855 71 : ok = head (filename, fd, n_units, count_lines, elide_from_end);
856 71 : if (!is_stdin && close (fd) != 0)
857 : {
858 0 : error (0, errno, _("closing %s"), quote (filename));
859 0 : return false;
860 : }
861 71 : return ok;
862 : }
863 :
864 : /* Convert a string of decimal digits, N_STRING, with an optional suffinx
865 : to an integral value. Upon successful conversion,
866 : return that value. If it cannot be converted, give a diagnostic and exit.
867 : COUNT_LINES indicates whether N_STRING is a number of bytes or a number
868 : of lines. It is used solely to give a more specific diagnostic. */
869 :
870 : static uintmax_t
871 68 : string_to_integer (bool count_lines, const char *n_string)
872 : {
873 : strtol_error s_err;
874 : uintmax_t n;
875 :
876 68 : s_err = xstrtoumax (n_string, NULL, 10, &n, "bkKmMGTPEZY0");
877 :
878 68 : if (s_err == LONGINT_OVERFLOW)
879 : {
880 2 : error (EXIT_FAILURE, 0,
881 : _("%s: %s is so large that it is not representable"), n_string,
882 : count_lines ? _("number of lines") : _("number of bytes"));
883 : }
884 :
885 66 : if (s_err != LONGINT_OK)
886 : {
887 15 : error (EXIT_FAILURE, 0, "%s: %s", n_string,
888 : (count_lines
889 : ? _("invalid number of lines")
890 : : _("invalid number of bytes")));
891 : }
892 :
893 51 : return n;
894 : }
895 :
896 : int
897 91 : main (int argc, char **argv)
898 : {
899 91 : enum header_mode header_mode = multiple_files;
900 91 : bool ok = true;
901 : int c;
902 : size_t i;
903 :
904 : /* Number of items to print. */
905 91 : uintmax_t n_units = DEFAULT_NUMBER;
906 :
907 : /* If true, interpret the numeric argument as the number of lines.
908 : Otherwise, interpret it as the number of bytes. */
909 91 : bool count_lines = true;
910 :
911 : /* Elide the specified number of lines or bytes, counting from
912 : the end of the file. */
913 91 : bool elide_from_end = false;
914 :
915 : /* Initializer for file_list if no file-arguments
916 : were specified on the command line. */
917 : static char const *const default_file_list[] = {"-", NULL};
918 : char const *const *file_list;
919 :
920 : initialize_main (&argc, &argv);
921 91 : program_name = argv[0];
922 91 : setlocale (LC_ALL, "");
923 : bindtextdomain (PACKAGE, LOCALEDIR);
924 : textdomain (PACKAGE);
925 :
926 91 : atexit (close_stdout);
927 :
928 91 : have_read_stdin = false;
929 :
930 91 : print_headers = false;
931 :
932 91 : if (1 < argc && argv[1][0] == '-' && ISDIGIT (argv[1][1]))
933 : {
934 30 : char *a = argv[1];
935 30 : char *n_string = ++a;
936 : char *end_n_string;
937 30 : char multiplier_char = 0;
938 :
939 : /* Old option syntax; a dash, one or more digits, and one or
940 : more option letters. Move past the number. */
941 139 : do ++a;
942 139 : while (ISDIGIT (*a));
943 :
944 : /* Pointer to the byte after the last digit. */
945 30 : end_n_string = a;
946 :
947 : /* Parse any appended option letters. */
948 43 : for (; *a; a++)
949 : {
950 14 : switch (*a)
951 : {
952 1 : case 'c':
953 1 : count_lines = false;
954 1 : multiplier_char = 0;
955 1 : break;
956 :
957 4 : case 'b':
958 : case 'k':
959 : case 'm':
960 4 : count_lines = false;
961 4 : multiplier_char = *a;
962 4 : break;
963 :
964 1 : case 'l':
965 1 : count_lines = true;
966 1 : break;
967 :
968 5 : case 'q':
969 5 : header_mode = never;
970 5 : break;
971 :
972 2 : case 'v':
973 2 : header_mode = always;
974 2 : break;
975 :
976 1 : default:
977 1 : error (0, 0, _("invalid trailing option -- %c"), *a);
978 1 : usage (EXIT_FAILURE);
979 : }
980 : }
981 :
982 : /* Append the multiplier character (if any) onto the end of
983 : the digit string. Then add NUL byte if necessary. */
984 29 : *end_n_string = multiplier_char;
985 29 : if (multiplier_char)
986 4 : *(++end_n_string) = 0;
987 :
988 29 : n_units = string_to_integer (count_lines, n_string);
989 :
990 : /* Make the options we just parsed invisible to getopt. */
991 29 : argv[1] = argv[0];
992 29 : argv++;
993 29 : argc--;
994 : }
995 :
996 207 : while ((c = getopt_long (argc, argv, "c:n:qv0123456789", long_options, NULL))
997 : != -1)
998 : {
999 56 : switch (c)
1000 : {
1001 1 : case PRESUME_INPUT_PIPE_OPTION:
1002 1 : presume_input_pipe = true;
1003 1 : break;
1004 :
1005 29 : case 'c':
1006 29 : count_lines = false;
1007 29 : elide_from_end = (*optarg == '-');
1008 29 : if (elide_from_end)
1009 17 : ++optarg;
1010 29 : n_units = string_to_integer (count_lines, optarg);
1011 16 : break;
1012 :
1013 10 : case 'n':
1014 10 : count_lines = true;
1015 10 : elide_from_end = (*optarg == '-');
1016 10 : if (elide_from_end)
1017 9 : ++optarg;
1018 10 : n_units = string_to_integer (count_lines, optarg);
1019 6 : break;
1020 :
1021 3 : case 'q':
1022 3 : header_mode = never;
1023 3 : break;
1024 :
1025 1 : case 'v':
1026 1 : header_mode = always;
1027 1 : break;
1028 :
1029 1 : case_GETOPT_HELP_CHAR;
1030 :
1031 0 : case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
1032 :
1033 11 : default:
1034 11 : if (ISDIGIT (c))
1035 1 : error (0, 0, _("invalid trailing option -- %c"), c);
1036 11 : usage (EXIT_FAILURE);
1037 : }
1038 : }
1039 :
1040 61 : if (header_mode == always
1041 58 : || (header_mode == multiple_files && optind < argc - 1))
1042 19 : print_headers = true;
1043 :
1044 61 : if ( ! count_lines && elide_from_end && OFF_T_MAX < n_units)
1045 : {
1046 : char umax_buf[INT_BUFSIZE_BOUND (uintmax_t)];
1047 0 : error (EXIT_FAILURE, 0, _("%s: number of bytes is too large"),
1048 : umaxtostr (n_units, umax_buf));
1049 : }
1050 :
1051 122 : file_list = (optind < argc
1052 37 : ? (char const *const *) &argv[optind]
1053 98 : : default_file_list);
1054 :
1055 : if (O_BINARY && ! isatty (STDOUT_FILENO))
1056 : freopen (NULL, "wb", stdout);
1057 :
1058 146 : for (i = 0; file_list[i]; ++i)
1059 85 : ok &= head_file (file_list[i], n_units, count_lines, elide_from_end);
1060 :
1061 61 : if (have_read_stdin && close (STDIN_FILENO) < 0)
1062 0 : error (EXIT_FAILURE, errno, "-");
1063 :
1064 61 : exit (ok ? EXIT_SUCCESS : EXIT_FAILURE);
1065 : }
|