#define _POSIX_C_SOURCE 200809L
#include <unistd.h>
#include <errno.h>
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

static int
head(FILE *file, uintmax_t count, const char *name)
{
    char *line = NULL;
    size_t capacity = 0;
    int status = 0;
    while (count--) {
        ssize_t n = getline(&line, &capacity, file);
        if (n < 0) {
            if (!feof(file)) { perror(name); status = 1; }
            break;
        }
        if (fwrite(line, 1, (size_t)n, stdout) != (size_t)n) {
            perror("head: stdout"); status = 1; break;
        }
    }
    free(line);
    return status;
}

int
main(int argc, char **argv)
{
    uintmax_t count = 10;
    int option, status = 0;
    while ((option = getopt(argc, argv, "n:")) != -1) {
        char *end;
        if (option != 'n') goto usage;
        errno = 0;
        if (!*optarg || strspn(optarg, "0123456789") != strlen(optarg)) goto usage;
        count = strtoumax(optarg, &end, 10);
        if (errno || *end) goto usage;
    }
    if (optind == argc) status = head(stdin, count, "head: stdin");
    for (; optind < argc; ++optind) {
        FILE *file = strcmp(argv[optind], "-") == 0 ? stdin : fopen(argv[optind], "r");
        if (file == NULL) { perror(argv[optind]); status = 1; continue; }
        status |= head(file, count, argv[optind]);
        if (file != stdin && fclose(file) == EOF) { perror(argv[optind]); status = 1; }
    }
    if (fflush(stdout) == EOF) { perror("head: stdout"); status = 1; }
    return status;
usage:
    fprintf(stderr, "usage: %s [-n number] [file...]\n", argv[0]);
    return 1;
}
