commit d27e24a1ac9c337f329adc033bee508788d4ee34
Author: FRIGN <[email protected]>
Date:   Thu Mar 5 00:58:12 2015 +0100

    Audit head(1)
    
    1) Use (s)size_t in head().
    2) BUGFIX: only check buf[len - 1] when len > 0, else there would
       be an overflow when getline returns 0 (which can happen) and a
       very potential segmentation fault.
    3) fix error-messages.
    4) update usage().
    5) argv-argc-style.
    6) clear up the main loop with if (newline).
    7) add newline before return.

diff --git a/README b/README
index 79170ea..524c369 100644
--- a/README
+++ b/README
@@ -35,7 +35,7 @@ The following tools are implemented ('*' == finished, '#' == 
UTF-8 support,
 =   find            yes                          none
 #*  fold            yes                          none
 =*  grep            yes                          none
-=*  head            yes                          none
+=*| head            yes                          none
 =*| hostname        non-posix                    none
 =*  kill            yes                          none
 =*| link            yes                          none
diff --git a/head.c b/head.c
index a66520e..0b17647 100644
--- a/head.c
+++ b/head.c
@@ -6,27 +6,25 @@
 #include "util.h"
 
 static void
-head(FILE *fp, const char *str, long n)
+head(FILE *fp, const char *fname, size_t n)
 {
        char *buf = NULL;
-       size_t size = 0;
+       size_t i = 0, size = 0;
        ssize_t len;
-       unsigned long i = 0;
 
-       while (i < n && ((len = getline(&buf, &size, fp)) != -1)) {
+       while (i < n && (len = getline(&buf, &size, fp)) >= 0) {
                fputs(buf, stdout);
-               if (buf[len - 1] == '\n')
-                       i++;
+               i += (len && (buf[len - 1] == '\n'));
        }
        free(buf);
        if (ferror(fp))
-               eprintf("%s: read error:", str);
+               eprintf("getline %s:", fname);
 }
 
 static void
 usage(void)
 {
-       eprintf("usage: %s [-n lines] [-N] [file...]\n", argv0);
+       eprintf("usage: %s [-n num] [-N] [file ...]\n", argv0);
 }
 
 int
@@ -34,8 +32,7 @@ main(int argc, char *argv[])
 {
        size_t n = 10;
        FILE *fp;
-       int ret = 0;
-       int newline, many;
+       int ret = 0, newline, many;
 
        ARGBEGIN {
        case 'n':
@@ -48,23 +45,25 @@ main(int argc, char *argv[])
                usage();
        } ARGEND;
 
-       if (argc == 0) {
+       if (!argc) {
                head(stdin, "<stdin>", n);
        } else {
                many = argc > 1;
-               for (newline = 0; argc > 0; argc--, argv++) {
-                       if (!(fp = fopen(argv[0], "r"))) {
-                               weprintf("fopen %s:", argv[0]);
+               for (newline = 0; *argv; argc--, argv++) {
+                       if (!(fp = fopen(*argv, "r"))) {
+                               weprintf("fopen %s:", *argv);
                                ret = 1;
                                continue;
                        }
+                       if (newline)
+                               putchar('\n');
                        if (many)
-                               printf("%s==> %s <==\n",
-                                      newline ? "\n" : "", argv[0]);
+                               printf("==> %s <==\n", *argv);
                        newline = 1;
-                       head(fp, argv[0], n);
+                       head(fp, *argv, n);
                        fclose(fp);
                }
        }
+
        return ret;
 }

Reply via email to