#include #include #include #include #include int head(const int fd, int lines) { static const size_t SIZE = 1024 * 4; char buffer[SIZE]; while (0 < lines) { const ssize_t available = read(fd, buffer, SIZE); if (-1 == available) return 1; if (0 == available) return 0; size_t offset = 0; for (ssize_t n = 0; n < available; ++n) { if (buffer[n] == '\n') { lines--; if (0 <= lines) { const ssize_t result = write(1, buffer + offset, 1 + n - offset); if (-1 == result) return 1; offset = 1 + n; } if (0 >= lines) return 0; } } if (0 < lines) { const ssize_t result = write(1, buffer + offset, available - offset); if (-1 == result) return 1; } } return 0; } int main(int argc, char * argv[]) { int opt; int lines = 10; while (-1 != (opt=getopt(argc, argv, "n:"))) { switch (opt) { case 'n': errno = 0; lines = strtol(optarg, (char **) NULL, 10); if (lines < 0) errno = EINVAL; if (0 != errno) { perror(optarg); return 1; } break; default: dprintf(2, "Usage: %s [-n lines] [file...]\n", argv[0]); return 1; } } const int files_count = argc - optind; int i = optind; int overall = 0; do { const char * const path = argc == i ? "-" : argv[i]; const unsigned int is_stdin = '-' == path[0] && 0 == path[1]; const int fd = is_stdin ? 0 : open(path, O_RDONLY); if (1 < files_count) printf(optind == i ? "==> %s <==\n" : "\n==> %s <==\n", path); if (0 <= fd) { const int result = head(fd, lines) | is_stdin ? 0 : close(fd); if (0 != result) perror(path); overall |= result; } else { perror(path); overall = 1; } } while (++i < argc); return overall; }