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 }