diff options
author | Aki <please@ignore.pl> | 2022-06-15 18:03:03 +0200 |
---|---|---|
committer | Aki <please@ignore.pl> | 2022-06-15 18:03:03 +0200 |
commit | b810fa6ab1d9d3fd7f6ac0b56a1e0e83a5c33b02 (patch) | |
tree | 37377baa953ecc5042ba9e683370571a49ce04bc | |
parent | 596df6ef9bfe023af103b821d9bf4fa0d0fbe788 (diff) | |
download | coreutils-b810fa6ab1d9d3fd7f6ac0b56a1e0e83a5c33b02.zip coreutils-b810fa6ab1d9d3fd7f6ac0b56a1e0e83a5c33b02.tar.gz coreutils-b810fa6ab1d9d3fd7f6ac0b56a1e0e83a5c33b02.tar.bz2 |
Added partial implementation of head
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | Makefile | 2 | ||||
-rw-r--r-- | head.c | 69 |
3 files changed, 71 insertions, 1 deletions
@@ -2,5 +2,6 @@ cat fallocate false +head ls true @@ -1,5 +1,5 @@ CFLAGS+=-std=c11 -Wall -Wextra -Wpedantic -D_POSIX_C_SOURCE=200809L -UTILS=cat fallocate false ls true +UTILS=cat fallocate false head ls true all: ${UTILS} @@ -0,0 +1,69 @@ +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> + + +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; + } + } + (void) head(0, lines, "<stdin>"); +} |