summaryrefslogtreecommitdiff
path: root/userland/minibox/utilities/cat.c
diff options
context:
space:
mode:
authorAnton Kling <anton@kling.gg>2023-10-22 19:50:38 +0200
committerAnton Kling <anton@kling.gg>2023-10-22 19:50:38 +0200
commit4e09bca9e34c226b6d7e34b4fa11248405fd988e (patch)
tree80f156b7940d9d19971395f335530170c69516c7 /userland/minibox/utilities/cat.c
Move everything into a new repo.
Diffstat (limited to 'userland/minibox/utilities/cat.c')
-rw-r--r--userland/minibox/utilities/cat.c54
1 files changed, 54 insertions, 0 deletions
diff --git a/userland/minibox/utilities/cat.c b/userland/minibox/utilities/cat.c
new file mode 100644
index 0000000..c528d49
--- /dev/null
+++ b/userland/minibox/utilities/cat.c
@@ -0,0 +1,54 @@
+// cat - concatenate and print files
+// https://pubs.opengroup.org/onlinepubs/9699919799/
+//
+// TODO: Add -u flag "Write bytes from the input file to the standard
+// output without delay as each is read."
+#include "include.h"
+#include <dirent.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+int fd_to_stdout(int fd) {
+ int rc;
+ for (char buffer[CAT_BUFFER]; (rc = read(fd, &buffer, sizeof(buffer)));) {
+ if (-1 == rc)
+ return 0;
+ if (-1 == write(fd_stdout, buffer, rc))
+ return 0;
+ }
+ return 1;
+}
+
+int cat_main(int argc, char **argv) {
+ int fd = fd_stdin;
+
+ // If no file operands are specified, the standard input shall be
+ // used.
+ if (argc < 2) {
+ return (fd_to_stdout(0)) ? 0 : 1;
+ }
+
+ argv++;
+ for (; *argv; argv++) {
+ // If a file is '-', the cat utility shall read from the standard
+ // input at that point in the sequence.
+ if (0 == strcmp(*argv, "-")) {
+ if (!fd_to_stdout(0))
+ return 1;
+ continue;
+ }
+
+ if (-1 == (fd = open(*argv, O_RDONLY, 0))) {
+ printf("cat: ");
+ // fflush(stdout);
+ perror(*argv);
+ return 1;
+ }
+ if (!fd_to_stdout(fd))
+ return 1;
+ close(fd);
+ }
+ return 0;
+}