From d5a64319f996f1fd5737db453f34d7509055d155 Mon Sep 17 00:00:00 2001 From: apio Date: Wed, 26 Oct 2022 20:51:20 +0200 Subject: [PATCH] apps: Add cat --- apps/Makefile | 2 +- apps/src/cat.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+), 1 deletion(-) create mode 100644 apps/src/cat.c diff --git a/apps/Makefile b/apps/Makefile index 66d0e8da..a6456fd8 100644 --- a/apps/Makefile +++ b/apps/Makefile @@ -1,4 +1,4 @@ -APPS := init sym sh crash uname uptime hello ps ls args +APPS := init sym sh crash uname uptime hello ps ls args cat APPS_DIR := $(LUNA_ROOT)/apps APPS_SRC := $(APPS_DIR)/src diff --git a/apps/src/cat.c b/apps/src/cat.c new file mode 100644 index 00000000..273b8d6a --- /dev/null +++ b/apps/src/cat.c @@ -0,0 +1,62 @@ +#define _GNU_SOURCE // for program_invocation_name +#include + +#include +#include +#include +#include + +void cat(FILE* stream) +{ + struct stat statbuf; + fstat(fileno(stream), &statbuf); + if (statbuf.st_mode == __VFS_DEVICE) // FIXME: Add S_ISDEV. + { + char buf[4096]; // FIXME: Do not limit ourselves to 4096 bytes. Devices which can't seek and are constant should + // return EOF after the first read. + fgets(buf, 4096, stream); + if (ferror(stream)) + { + perror(program_invocation_name); + exit(EXIT_FAILURE); + } + if (feof(stream)) return; + fputs(buf, stdout); + return; + } + char buf[BUFSIZ]; + do { + fgets(buf, BUFSIZ, stream); + if (ferror(stream)) + { + perror(program_invocation_name); + exit(EXIT_FAILURE); + } + fputs(buf, stdout); + } while (!feof(stream)); +} + +int main(int argc, char** argv) +{ + if (argc == 1) cat(stdin); + else + { + for (int i = 1; i < argc; i++) + { + if (strcmp(argv[i], "-") == 0) cat(stdin); + else if (strcmp(argv[i], "-n") == 0 || strcmp(argv[i], "--newline") == 0) + putchar('\n'); + else + { + FILE* stream = fopen(argv[i], "r"); + if (!stream) + { + perror(program_invocation_name); + return EXIT_FAILURE; + } + cat(stream); + fclose(stream); + } + } + } +} \ No newline at end of file