2 * head.c - copy the first part of files
5 * Build: c89 -o head head.c
6 * Source: <http://pdcore.sourceforge.net/>
7 * Spec: <http://www.opengroup.org/onlinepubs/9699919799/utilities/head.html>
9 * This is free and unencumbered software released into the public domain,
10 * provided "as is", without warranty of any kind, express or implied. See the
11 * file UNLICENSE and the website <http://unlicense.org> for further details.
24 #include <sys/types.h>
27 #define USAGE "usage: head [-n number] [file ...]\n"
30 static long ctol(char *s);
31 static void headfile(int fd, char *fn, int lines);
32 static void error(char *s);
34 static int exitstatus;
37 int main(int argc, char **argv)
39 extern int opterr, optind;
41 int c, fd, many, first;
45 setlocale(LC_ALL, "");
48 while ((c = getopt(argc, argv, "n:")) != -1)
52 if (*optarg && (lines = ctol(optarg)) > 0)
54 /* else fall through */
56 fprintf(stderr, USAGE);
61 headfile(STDIN_FILENO, "stdin", lines);
64 many = (optind + 1 < argc) ? 1 : 0;
77 printf("==> %s <==\n", fn);
80 if (strcmp(fn, "-") == 0)
81 headfile(STDIN_FILENO, "stdin", lines);
83 if ((fd = open(fn, O_RDONLY)) == -1)
87 headfile(fd, fn, lines);
103 /* only copes with non-zero, optionally signed, */
104 /* decimal integers; that's all we need */
105 if (! (isdigit(*c) || *c == '+' || *c == '-'))
112 return (badch ? 0 : atol(s));
116 void headfile(int fd, char *fn, int lines)
118 unsigned char buf[BUFSIZE], *c;
123 if ((n = read(fd, buf, BUFSIZE)) <= 0)
126 for (c = buf; lines && c < (buf + n); c++)
130 o = lines ? n : c - buf;
131 if (write(STDOUT_FILENO, buf, (size_t)o) != o)
145 fprintf(stderr, "head: %s: %s\n", s, strerror(errno));