From b810fa6ab1d9d3fd7f6ac0b56a1e0e83a5c33b02 Mon Sep 17 00:00:00 2001 From: Aki Date: Wed, 15 Jun 2022 18:03:03 +0200 Subject: Added partial implementation of head --- .gitignore | 1 + Makefile | 2 +- head.c | 69 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 71 insertions(+), 1 deletion(-) create mode 100644 head.c diff --git a/.gitignore b/.gitignore index f2bfd53..a2d3955 100644 --- a/.gitignore +++ b/.gitignore @@ -2,5 +2,6 @@ cat fallocate false +head ls true diff --git a/Makefile b/Makefile index 8694215..cd44d92 100644 --- a/Makefile +++ b/Makefile @@ -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} diff --git a/head.c b/head.c new file mode 100644 index 0000000..b372a30 --- /dev/null +++ b/head.c @@ -0,0 +1,69 @@ +#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; + } + } + (void) head(0, lines, ""); +} -- cgit v1.1