head.c - sbase - suckless unix tools
(HTM) git clone git://git.suckless.org/sbase
(DIR) Log
(DIR) Files
(DIR) Refs
(DIR) README
(DIR) LICENSE
---
head.c (1383B)
---
1 /* See LICENSE file for copyright and license details. */
2 #include <stdint.h>
3 #include <stdio.h>
4 #include <stdlib.h>
5 #include <string.h>
6
7 #include "util.h"
8
9 static void
10 head(FILE *fp, const char *fname, size_t n)
11 {
12 char *buf = NULL;
13 size_t i = 0, size = 0;
14 ssize_t len;
15
16 while (i < n && (len = getline(&buf, &size, fp)) > 0) {
17 fwrite(buf, 1, len, stdout);
18 i += (len && (buf[len - 1] == '\n'));
19 }
20 free(buf);
21 if (ferror(fp))
22 eprintf("getline %s:", fname);
23 }
24
25 static void
26 usage(void)
27 {
28 eprintf("usage: %s [-num | -n num] [file ...]\n", argv0);
29 }
30
31 int
32 main(int argc, char *argv[])
33 {
34 size_t n = 10;
35 FILE *fp;
36 int ret = 0, newline = 0, many = 0;
37
38 ARGBEGIN {
39 case 'n':
40 n = estrtonum(EARGF(usage()), 0, MIN(LLONG_MAX, SIZE_MAX));
41 break;
42 ARGNUM:
43 n = ARGNUMF();
44 break;
45 default:
46 usage();
47 } ARGEND
48
49 if (!argc) {
50 head(stdin, "<stdin>", n);
51 } else {
52 many = argc > 1;
53 for (newline = 0; *argv; argc--, argv++) {
54 if (!strcmp(*argv, "-")) {
55 *argv = "<stdin>";
56 fp = stdin;
57 } else if (!(fp = fopen(*argv, "r"))) {
58 weprintf("fopen %s:", *argv);
59 ret = 1;
60 continue;
61 }
62 if (many) {
63 if (newline)
64 putchar('\n');
65 printf("==> %s <==\n", *argv);
66 }
67 newline = 1;
68 head(fp, *argv, n);
69 if (fp != stdin && fshut(fp, *argv))
70 ret = 1;
71 }
72 }
73
74 ret |= fshut(stdin, "<stdin>") | fshut(stdout, "<stdout>");
75
76 return ret;
77 }