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 }