summaryrefslogtreecommitdiff
path: root/src/user/app/shell/builtins.c
diff options
context:
space:
mode:
authordzwdz2022-07-31 17:09:05 +0200
committerdzwdz2022-07-31 20:56:52 +0200
commit70948d9a9ec613b17c2cdff9e76b5b35f40565ac (patch)
tree5c2b0b6444369b8019c34abcae66244589eb6446 /src/user/app/shell/builtins.c
parent40674fa5469c7af09095d5dd5cca8eccc728561c (diff)
user/shell: use an array of function pointers for the builtins
Diffstat (limited to 'src/user/app/shell/builtins.c')
-rw-r--r--src/user/app/shell/builtins.c105
1 files changed, 75 insertions, 30 deletions
diff --git a/src/user/app/shell/builtins.c b/src/user/app/shell/builtins.c
index 3a19a2f..e272cf3 100644
--- a/src/user/app/shell/builtins.c
+++ b/src/user/app/shell/builtins.c
@@ -4,54 +4,55 @@
#include <string.h>
#include <unistd.h>
-void cmd_cat_ls(const char *args, bool ls) {
+static void cmd_cat(int argc, const char **argv) {
+ // TODO loop over argv
+
FILE *file;
static char buf[512];
- int len; // first used for strlen(args), then length of buffer
-
- if (args) {
- len = strlen(args);
- memcpy(buf, args, len + 1); // no overflow check - the shell is just a PoC
- if (ls) { // paths to directories always have a trailing slash
- if (buf[len-1] != '/') {
- buf[len] = '/';
- buf[len+1] = '\0';
- }
- }
-
- file = fopen(buf, "r");
- } else if (ls) { /* ls default argument */
- file = fopen("/", "r");
- } else { /* cat default argument */
+ if (argv[1])
+ file = fopen(argv[1], "r");
+ else
file = file_clone(stdin);
- }
if (!file) {
eprintf("couldn't open");
return;
}
- while (!feof(file)) {
+ for (;;) {
int len = fread(buf, 1, sizeof buf, file);
if (len <= 0) break;
-
- if (ls) {
- for (int i = 0; i < len; i++)
- if (buf[i] == '\0') buf[i] = '\n';
- }
fwrite(buf, 1, len, stdout);
}
fclose(file);
}
-void cmd_hexdump(const char *args) {
+static void cmd_echo(int argc, const char **argv) {
+ bool newline = true;
+ int i = 1;
+
+ if (!strcmp("-n", argv[i])) {
+ i++;
+ newline = false;
+ }
+
+ printf("%s", argv[i++]);
+ for (; argv[i]; i++)
+ printf(" %s", argv[i]);
+ if (newline)
+ printf("\n");
+}
+
+void cmd_hexdump(int argc, const char **argv) {
+ // TODO loop over argv
+ // TODO use fopen/fread
static uint8_t buf[512];
int fd, len;
- fd = _syscall_open(args, strlen(args), 0);
+ fd = _syscall_open(argv[1], strlen(argv[1]), 0);
if (fd < 0) {
- eprintf("couldn't open %s", args);
+ eprintf("couldn't open %s", argv[1]);
return;
}
@@ -77,11 +78,55 @@ void cmd_hexdump(const char *args) {
close(fd);
}
-void cmd_touch(const char *args) {
- int fd = _syscall_open(args, strlen(args), OPEN_CREATE);
+static void cmd_ls(int argc, const char **argv) {
+ // TODO loop over argv
+ FILE *file;
+ static char buf[512];
+
+ if (argv[1]) {
+ int len = strlen(argv[1]);
+ memcpy(buf, argv[1], len + 1); // TODO no overflow check
+
+ if (buf[len-1] != '/') {
+ buf[len] = '/';
+ buf[len+1] = '\0';
+ }
+
+ file = fopen(buf, "r");
+ } else {
+ file = fopen("/", "r");
+ }
+
+ if (!file) {
+ eprintf("couldn't open");
+ return;
+ }
+
+ for (;;) {
+ int len = fread(buf, 1, sizeof buf, file);
+ if (len <= 0) break;
+ for (int i = 0; i < len; i++)
+ if (buf[i] == '\0') buf[i] = '\n';
+ fwrite(buf, 1, len, stdout);
+ }
+ fclose(file);
+}
+
+static void cmd_touch(int argc, const char **argv) {
+ // TODO loop over argv
+ int fd = _syscall_open(argv[1], strlen(argv[1]), OPEN_CREATE);
if (fd < 0) {
- eprintf("couldn't touch %s\n", args);
+ eprintf("couldn't touch %s\n", argv[1]);
return;
}
close(fd);
}
+
+struct builtin builtins[] = {
+ {"cat", cmd_cat},
+ {"echo", cmd_echo},
+ {"hexdump", cmd_hexdump},
+ {"ls", cmd_ls},
+ {"touch", cmd_touch},
+ {NULL, NULL},
+};