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 }