1 /* head -- output first part of file(s)
2 Copyright (C) 1989, 1990, 1991, 1995 Free Software Foundation, Inc.
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2, or (at your option)
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
18 /* Options: (see usage)
19 Reads from standard input if no files are given or when a filename of
21 By default, filename headers are printed only if more than one file
23 By default, prints the first 10 lines (head -n 10).
25 David MacKenzie <djm@gnu.ai.mit.edu> */
31 #include <sys/types.h>
36 /* Number of lines/chars/blocks to head. */
37 #define DEFAULT_NUMBER 10
39 /* Size of atomic reads. */
40 #define BUFSIZE (512 * 8)
42 /* Number of bytes per item we are printing.
43 If 0, head in lines. */
46 /* If nonzero, print filename headers. */
47 static int print_headers;
49 /* When to print the filename banners. */
52 multiple_files, always, never
58 static int head_bytes ();
59 static int head_file ();
60 static int head_lines ();
62 static void parse_unit ();
64 static void write_header ();
66 /* The name this program was run with. */
69 /* Have we ever read standard input? */
70 static int have_read_stdin;
72 /* If non-zero, display usage information and exit. */
75 /* If non-zero, print the version on standard output then exit. */
76 static int show_version;
78 static struct option const long_options[] =
80 {"bytes", required_argument, NULL, 'c'},
81 {"lines", required_argument, NULL, 'n'},
82 {"quiet", no_argument, NULL, 'q'},
83 {"silent", no_argument, NULL, 'q'},
84 {"verbose", no_argument, NULL, 'v'},
85 {"help", no_argument, &show_help, 1},
86 {"version", no_argument, &show_version, 1},
95 enum header_mode header_mode = multiple_files;
97 long number = -1; /* Number of items to print (-1 if undef.). */
98 int c; /* Option character. */
100 program_name = argv[0];
105 if (argc > 1 && argv[1][0] == '-' && ISDIGIT (argv[1][1]))
107 /* Old option syntax; a dash, one or more digits, and one or
108 more option letters. Move past the number. */
109 for (number = 0, ++argv[1]; ISDIGIT (*argv[1]); ++argv[1])
110 number = number * 10 + *argv[1] - '0';
111 /* Parse any appended option letters. */
141 header_mode = always;
145 error (0, 0, "unrecognized option `-%c'", *argv[1]);
150 /* Make the options we just parsed invisible to getopt. */
156 while ((c = getopt_long (argc, argv, "c:n:qv", long_options, (int *) 0))
171 number = atou (optarg);
173 error (1, 0, "invalid number `%s'", optarg);
181 header_mode = always;
191 printf ("head - %s\n", version_string);
199 number = DEFAULT_NUMBER;
204 if (header_mode == always
205 || (header_mode == multiple_files && optind < argc - 1))
209 exit_status |= head_file ("-", number);
211 for (; optind < argc; ++optind)
212 exit_status |= head_file (argv[optind], number);
214 if (have_read_stdin && close (0) < 0)
215 error (1, errno, "-");
216 if (fclose (stdout) == EOF)
217 error (1, errno, "write error");
223 head_file (filename, number)
229 if (!strcmp (filename, "-"))
232 filename = "standard input";
234 write_header (filename);
235 return head (filename, 0, number);
239 fd = open (filename, O_RDONLY);
245 write_header (filename);
246 errors = head (filename, fd, number);
250 error (0, errno, "%s", filename);
256 write_header (filename)
259 static int first_file = 1;
261 printf ("%s==> %s <==\n", (first_file ? "" : "\n"), filename);
266 head (filename, fd, number)
272 return head_bytes (filename, fd, number);
274 return head_lines (filename, fd, number);
278 head_bytes (filename, fd, bytes_to_write)
283 char buffer[BUFSIZE];
286 while (bytes_to_write)
288 bytes_read = safe_read (fd, buffer, BUFSIZE);
291 error (0, errno, "%s", filename);
296 if (bytes_read > bytes_to_write)
297 bytes_read = bytes_to_write;
298 if (fwrite (buffer, 1, bytes_read, stdout) == 0)
299 error (1, errno, "write error");
300 bytes_to_write -= bytes_read;
306 head_lines (filename, fd, lines_to_write)
311 char buffer[BUFSIZE];
315 while (lines_to_write)
317 bytes_read = safe_read (fd, buffer, BUFSIZE);
320 error (0, errno, "%s", filename);
326 while (bytes_to_write < bytes_read)
327 if (buffer[bytes_to_write++] == '\n' && --lines_to_write == 0)
329 if (fwrite (buffer, 1, bytes_to_write, stdout) == 0)
330 error (1, errno, "write error");
339 int arglen = strlen (str);
344 switch (str[arglen - 1])
348 str[arglen - 1] = '\0';
352 str[arglen - 1] = '\0';
356 str[arglen - 1] = '\0';
361 /* Convert STR, a string of ASCII digits, into an unsigned integer.
362 Return -1 if STR does not represent a valid unsigned integer. */
370 for (value = 0; ISDIGIT (*str); ++str)
371 value = value * 10 + *str - '0';
372 return *str ? -1 : value;
380 fprintf (stderr, "Try `%s --help' for more information.\n",
385 Usage: %s [OPTION]... [FILE]...\n\
390 -c, --bytes=SIZE print first SIZE bytes\n\
391 -n, --lines=NUMBER print first NUMBER lines instead of first 10\n\
392 -q, --quiet, --silent never print headers giving file names\n\
393 -v, --verbose always print headers giving file names\n\
394 --help display this help and exit\n\
395 --version output version information and exit\n\
397 SIZE may have a multiplier suffix: b for 512, k for 1K, m for 1 Meg.\n\
398 If -VALUE is used as first OPTION, read -c VALUE when one of\n\
399 multipliers bkm follows concatenated, else read -n VALUE. With no\n\
400 FILE, or when FILE is -, read standard input.\n\