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

static int
cat(int fd, const char *name)
{
    char buf[8192];
    for (;;) {
        ssize_t n = read(fd, buf, sizeof(buf));
        size_t used = 0;
        if (n < 0 && errno == EINTR) continue;
        if (n < 0) { perror(name); return 1; }
        if (n == 0) return 0;
        while (used < (size_t)n) {
            ssize_t written = write(STDOUT_FILENO, buf + used, (size_t)n - used);
            if (written < 0 && errno == EINTR) continue;
            if (written <= 0) { perror("cat: stdout"); return 1; }
            used += (size_t)written;
        }
    }
}

int
main(int argc, char **argv)
{
    int i, status = 0;
    if (argc == 1) return cat(STDIN_FILENO, "cat: stdin");
    for (i = 1; i < argc; ++i) {
        int fd = strcmp(argv[i], "-") == 0 ? STDIN_FILENO : open(argv[i], O_RDONLY);
        if (fd < 0) { perror(argv[i]); status = 1; continue; }
        status |= cat(fd, argv[i]);
        if (fd != STDIN_FILENO && close(fd) < 0) { perror(argv[i]); status = 1; }
    }
    return status;
}
