From 340ca1a5bdf9a03819872f7370891b6bf5529441 Mon Sep 17 00:00:00 2001 From: Victor Mignot Date: Wed, 4 Mar 2026 15:04:26 +0100 Subject: Add `cat` implementation --- src/cat.c | 74 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100644 src/cat.c (limited to 'src/cat.c') diff --git a/src/cat.c b/src/cat.c new file mode 100644 index 0000000..2370d29 --- /dev/null +++ b/src/cat.c @@ -0,0 +1,74 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#define CAT_USAGE "Usage: cat [-u] [file...]\n" +#define STDIN_ARG "-" +#define BUFFER_SIZE 20480 + +static void close_file(int fd) { + if (fd != STDIN_FILENO) { + close(fd); + } +} + +static bool print_file_content(const char *path) { + char buffer[BUFFER_SIZE]; + int input = -1; + ssize_t ret = -1; + + if (strcmp(path, STDIN_ARG) == 0) { + input = STDIN_FILENO; + } else { + if ((input = open(path, O_RDONLY)) == -1) { + fprintf(stderr,"Can't open file '%s': %s\n", path, strerror(errno)); + return false; + } + } + + do { + ret = read(input, buffer, BUFFER_SIZE); + if (ret > 0) { + write(STDOUT_FILENO, buffer, ret); + } + } while (ret > 0); + + if (ret == -1) { + fprintf(stderr, "Failed to read file '%s': %s\n", path, strerror(errno)); + } + + close_file(input); + + return ret == 0; +} + +int cat_main(int argc, char *argv[]) { + int opt = 0; + bool ret = false; + + while ((opt = getopt(argc, argv, "u")) != -1) { + if (opt != 'u') { + perror(CAT_USAGE); + return EXIT_FAILURE; + } + } + + for (int i = optind; i < argc; i++) { + ret = print_file_content(argv[i]); + if (!ret) { + break; + } + } + + /* If no argument was provided, we use stdin by default */ + if (argc - optind == 0) { + ret = print_file_content(STDIN_ARG); + } + + return ret ? EXIT_SUCCESS : EXIT_FAILURE; +} -- cgit v1.2.3