diff options
| author | Victor Mignot <victor@vmignot.fr> | 2026-03-04 15:04:26 +0100 |
|---|---|---|
| committer | Victor Mignot <victor@vmignot.fr> | 2026-03-04 17:25:25 +0100 |
| commit | d66a5a290132c12e6f512568dde5470f08386e53 (patch) | |
| tree | 6ea12385c087d5bdecf801a5f6b1c0b4c8670d0f /src/cat.c | |
| parent | 40b83a70db46f7a8fc17fa94a93adadd95840a2c (diff) | |
| download | futiles-d66a5a290132c12e6f512568dde5470f08386e53.tar.gz | |
Diffstat (limited to 'src/cat.c')
| -rw-r--r-- | src/cat.c | 74 |
1 files changed, 74 insertions, 0 deletions
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 <errno.h> +#include <fcntl.h> +#include <getopt.h> +#include <stdbool.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#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; +} |
