aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/basename.c17
-rw-r--r--src/cat.c74
-rw-r--r--src/false.c5
-rw-r--r--src/main.c15
-rw-r--r--src/true.c4
5 files changed, 90 insertions, 25 deletions
diff --git a/src/basename.c b/src/basename.c
index e07a7ee..1785754 100644
--- a/src/basename.c
+++ b/src/basename.c
@@ -4,8 +4,7 @@
#include <stdio.h>
#include <string.h>
-#define BASENAME_OUT_FMT "%s\n"
-#define BASENAME_USAGE "Usage: basename NAME [SUFFIX]\n"
+#define BASENAME_USAGE "Usage: basename NAME [SUFFIX]\n"
#define BASENAME_USE "Return non-directory portion of a pathname\n"
static char *remove_trailing_slashes(char *pathname) {
@@ -33,7 +32,7 @@ int basename_main(int argc, char *argv[]) {
if (getopt(argc, argv, "") != -1) {
- fprintf(stderr, BASENAME_USAGE);
+ fputs(BASENAME_USAGE, stderr);
return EXIT_FAILURE;
}
@@ -45,16 +44,16 @@ int basename_main(int argc, char *argv[]) {
result = argv[1];
suffix = argc == 3 ? argv[2] : NULL;
- /* Return "" on empty input string */
+ /* Return empty string on empty input string */
if (result[0] == '\0') {
- printf(BASENAME_OUT_FMT, "");
+ puts("");
return EXIT_SUCCESS;
}
/* Remove trailing whitespace and return "/" if the path was all slashes */
last_char = remove_trailing_slashes(result);
if (last_char == result) {
- printf(BASENAME_OUT_FMT, "/");
+ puts("/");
return EXIT_SUCCESS;
}
@@ -65,13 +64,13 @@ int basename_main(int argc, char *argv[]) {
/* Remove suffix or return it as is if it's equal to last_node */
if (suffix == NULL) {
- printf(BASENAME_OUT_FMT, result);
+ puts(result);
return EXIT_SUCCESS;
}
suffix_len = strlen(suffix);
if (suffix_len > strlen(result)) {
- printf(BASENAME_OUT_FMT, result);
+ puts(result);
return EXIT_SUCCESS;
}
@@ -88,6 +87,6 @@ int basename_main(int argc, char *argv[]) {
*cursor = '\0';
}
- printf(BASENAME_OUT_FMT, result);
+ puts(result);
return EXIT_SUCCESS;
}
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;
+}
diff --git a/src/false.c b/src/false.c
index 2601ae2..f30e835 100644
--- a/src/false.c
+++ b/src/false.c
@@ -1,6 +1,3 @@
-int false_main(int argc, char *argv[]) {
- (void) argc;
- (void) argv;
-
+int false_main([[maybe_unused]] int argc, [[maybe_unused]] char *argv[]) {
return 1;
}
diff --git a/src/main.c b/src/main.c
index 605a2a0..80f369d 100644
--- a/src/main.c
+++ b/src/main.c
@@ -8,6 +8,7 @@ typedef int util_main(int, char **);
extern util_main true_main;
extern util_main false_main;
extern util_main basename_main;
+extern util_main cat_main;
typedef struct futiles_util futiles_util_t;
struct futiles_util {
@@ -20,26 +21,22 @@ const futiles_util_t utils[] = {
{ .name = "futiles", .main = display_utils },
{ .name = "true", .main = true_main },
{ .name = "false", .main = false_main },
- { .name = "basename", .main = basename_main }
+ { .name = "basename", .main = basename_main },
+ { .name = "cat", .main = cat_main }
};
#define UTILS_NB (sizeof(utils) / sizeof(futiles_util_t))
-int display_utils(int argc, char *argv[]) {
- (void) argc;
- (void) argv;
-
- printf("Available utils: ");
+int display_utils([[maybe_unused]] int argc, [[maybe_unused]] char *argv[]) {
+ fputs("Available utils: ", stdout);
for (size_t i = 1; i < UTILS_NB; i++) {
printf("%s ", utils[i].name);
}
- printf("\n");
+ putc('\n', stdout);
return EXIT_SUCCESS;
}
int main(int argc, char *argv[]) {
- (void) argc;
-
char *called_basename = basename(argv[0]);
for (size_t i = 0; i < UTILS_NB; i++) {
diff --git a/src/true.c b/src/true.c
index d7d4dfb..aed6117 100644
--- a/src/true.c
+++ b/src/true.c
@@ -1,5 +1,3 @@
-int true_main(int argc, char *argv[]) {
- (void) argc;
- (void) argv;
+int true_main([[maybe_unused]] int argc, [[maybe_unused]] char *argv[]) {
return 0;
}