head.c - sbase - suckless unix tools | |
git clone git://git.suckless.org/sbase | |
Log | |
Files | |
Refs | |
README | |
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 } |