#include #include #include #include #include int head(int fd, int lines, const char * name) { static const size_t SIZE = 1024 * 4; char buffer[SIZE]; while (lines > 0) { const ssize_t available = read(fd, buffer, SIZE); if (-1 == available) { perror(name); 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 res = write(1, buffer + offset, 1 + n - offset); if (-1 == res) { perror(name); return 1; } offset = 1 + n; } if (0 >= lines) return 0; } } if (0 < lines) { const ssize_t res = write(1, buffer + offset, available - offset); if (-1 == res) { perror(name); 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 unsigned int file_count = argc - optind; int res = 0; if (optind >= argc) res |= head(0, lines, "-"); else for (int i = optind; i < argc; ++i) { if (1 < file_count) printf("==> %s <==\n", argv[i]); const unsigned int is_stdin = '-' == argv[i][0] && 0 == argv[i][1]; const int fd = is_stdin ? 0 : open(argv[i], O_RDONLY); if (-1 == fd) { perror(argv[i]); res = 1; continue; } res |= head(fd, lines, argv[i]); if (!is_stdin) { const int clr = close(fd); if (-1 == clr) { perror(argv[i]); res = 1; } } } return res; }