diff options
author | dzwdz | 2022-12-27 22:42:06 +0100 |
---|---|---|
committer | dzwdz | 2022-12-27 22:42:06 +0100 |
commit | 8ac68ecab5734d5c5f3638397e5a9e6084fe7737 (patch) | |
tree | 209fcf07d7d4c5f3555a3f78800ba86bd91482c7 /src/user | |
parent | 35a82cb0dae43eb538de7afa1da77c4e249ba4e4 (diff) |
sh: minor usability / aesthetic improvements
Diffstat (limited to 'src/user')
-rw-r--r-- | src/user/app/init/init.c | 3 | ||||
-rw-r--r-- | src/user/app/shell/builtins.c | 42 | ||||
-rw-r--r-- | src/user/app/shell/shell.c | 69 | ||||
-rw-r--r-- | src/user/app/shell/shell.h | 2 | ||||
-rw-r--r-- | src/user/lib/err.c | 14 | ||||
-rw-r--r-- | src/user/lib/include/err.h | 2 |
6 files changed, 61 insertions, 71 deletions
diff --git a/src/user/app/init/init.c b/src/user/app/init/init.c index 10511b8..96b2eb7 100644 --- a/src/user/app/init/init.c +++ b/src/user/app/init/init.c @@ -21,8 +21,9 @@ void redirect(const char *exe, const char *out, const char *in) { for (;;) { if (!fork()) { + const char *argv[] = {exe, NULL}; termcook(); - execv(exe, NULL); + execv(exe, (void*)argv); fprintf(stderr, "init: couldn't start %s\n", exe); _syscall_sleep(5000); exit(1); diff --git a/src/user/app/shell/builtins.c b/src/user/app/shell/builtins.c index 4ea6c9a..870a6af 100644 --- a/src/user/app/shell/builtins.c +++ b/src/user/app/shell/builtins.c @@ -1,14 +1,15 @@ #include "builtins.h" #include "shell.h" #include <camellia.h> +#include <camellia/fs/misc.h> #include <camellia/path.h> +#include <err.h> #include <stdbool.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/stat.h> #include <unistd.h> -#include <camellia/fs/misc.h> #define DEFAULT_ARGV(...) \ char *_argv_default[] = {argv[0], __VA_ARGS__}; \ @@ -55,15 +56,11 @@ static void cmd_echo(int argc, char **argv) { } void cmd_getsize(int argc, char **argv) { - if (argc < 2) { - eprintf("missing arguments"); - return; - } - + if (argc < 2) errx(1, "no arguments"); for (int i = 1; i < argc; i++) { handle_t h = camellia_open(argv[i], OPEN_READ); if (h < 0) { - eprintf("error opening %s", argv[i]); + warn("error opening %s", argv[i]); continue; } printf("%s: %d\n", argv[i], (int)_syscall_getsize(h)); @@ -76,7 +73,7 @@ void cmd_hexdump(int argc, char **argv) { const size_t buflen = 4096; uint8_t *buf = malloc(buflen); FILE *file; - bool canonical = !strcmp(argv[0], "hd"); + bool canonical = strcmp(argv[0], "hd") == 0; size_t readlen = ~0; size_t pos = 0; bool raw = false; @@ -107,8 +104,8 @@ void cmd_hexdump(int argc, char **argv) { for (; optind < argc; optind++) { file = fopen(argv[optind], "r"); if (!file) { - eprintf("couldn't open %s", argv[optind]); - return; + warn("couldn't open %s", argv[optind]); + continue; } if (raw) fextflags(file, FEXT_NOFILL); fseek(file, pos, SEEK_SET); @@ -175,8 +172,8 @@ static void cmd_ls(int argc, char **argv) { file = fopen(path, "r"); if (!file) { - eprintf("couldn't open %s", argv[i]); - return; + warn("couldn't open %s", argv[i]); + continue; } for (;;) { int len = fread(buf, 1, buflen, file); @@ -191,10 +188,7 @@ static void cmd_ls(int argc, char **argv) { static void cmd_mkdir(int argc, char **argv) { // TODO mkdir -p - if (argc < 2) { - eprintf("no arguments"); - return; - } + if (argc < 2) errx(1, "no arguments"); for (int i = 1; i < argc; i++) { if (mkdir(argv[i], 0777) < 0) perror(argv[i]); @@ -202,10 +196,7 @@ static void cmd_mkdir(int argc, char **argv) { } static void cmd_rm(int argc, char **argv) { - if (argc < 2) { - eprintf("no arguments"); - return; - } + if (argc < 2) errx(1, "no arguments"); for (int i = 1; i < argc; i++) { if (unlink(argv[i]) < 0) perror(argv[i]); @@ -213,19 +204,12 @@ static void cmd_rm(int argc, char **argv) { } static void cmd_sleep(int argc, char **argv) { - if (argc < 2) { - eprintf("no arguments"); - return; - } + if (argc < 2) errx(1, "no arguments"); _syscall_sleep(strtol(argv[1], NULL, 0) * 1000); } static void cmd_touch(int argc, char **argv) { - if (argc <= 1) { - eprintf("no arguments"); - return; - } - + if (argc < 2) errx(1, "no arguments"); for (int i = 1; i < argc; i++) { FILE *f = fopen(argv[i], "a"); if (!f) perror(argv[i]); diff --git a/src/user/app/shell/shell.c b/src/user/app/shell/shell.c index 365e087..909d625 100644 --- a/src/user/app/shell/shell.c +++ b/src/user/app/shell/shell.c @@ -2,6 +2,7 @@ #include "shell.h" #include <camellia/flags.h> #include <camellia/syscalls.h> +#include <err.h> #include <errno.h> #include <stdbool.h> #include <stdio.h> @@ -15,23 +16,20 @@ int main(); static void execp(char **argv) { if (!argv || !*argv) return; - if (argv[0][0] == '/') { + if (strncmp(argv[0], "/", 1) == 0 || + strncmp(argv[0], "./", 2) == 0 || + strncmp(argv[0], "../", 3) == 0) + { execv(argv[0], argv); - return; - } - - size_t cmdlen = strlen(argv[0]); - char *s = malloc(cmdlen); - if (!s) { - eprintf("out of memory."); - exit(1); + } else { + size_t cmdlen = strlen(argv[0]); + char *s = malloc(cmdlen + 6); + if (!s) err(1, "malloc"); + memcpy(s, "/bin/", 5); + memcpy(s + 5, argv[0], cmdlen + 1); + execv(s, argv); + free(s); } - memcpy(s, "/bin/", 5); - memcpy(s + 5, argv[0], cmdlen + 1); - argv[0] = s; - - execv(s, argv); - free(s); } void run_args(int argc, char **argv, struct redir *redir) { @@ -40,7 +38,7 @@ void run_args(int argc, char **argv, struct redir *redir) { /* "special" commands that can't be handled in a subprocess */ if (!strcmp(argv[0], "mount")) { if (argc < 3) { - eprintf("not enough arguments"); + fprintf(stderr, "mount: not enough arguments\n"); return; } MOUNT_AT(argv[1]) { @@ -71,26 +69,20 @@ void run_args(int argc, char **argv, struct redir *redir) { if (redir && redir->stdout) { FILE *f = fopen(redir->stdout, redir->append ? "a" : "w"); if (!f) { - eprintf("couldn't open %s for redirection", redir->stdout); - exit(1); + err(1, "couldn't open %s for redirection", redir->stdout); } /* a workaround for file offsets not being preserved across exec()s. * TODO document that weird behaviour of exec() */ - handle_t p[2]; if (_syscall_pipe(p, 0) < 0) { - eprintf("couldn't create redirection pipe", redir->stdout); - exit(1); + errx(1, "couldn't create redirection pipe"); } if (!_syscall_fork(FORK_NOREAP, NULL)) { /* the child forwards data from the pipe to the file */ const size_t buflen = 512; char *buf = malloc(buflen); - if (!buf) { - eprintf("when redirecting: malloc failure"); - exit(1); - } + if (!buf) err(1, "when redirecting"); close(p[1]); for (;;) { long len = _syscall_read(p[0], buf, buflen, 0); @@ -103,13 +95,13 @@ void run_args(int argc, char **argv, struct redir *redir) { fclose(f); close(p[0]); if (_syscall_dup(p[1], 1, 0) < 0) { - eprintf("dup failure"); - exit(1); + errx(1, "dup() failed when redirecting"); } } for (struct builtin *iter = builtins; iter->name; iter++) { if (!strcmp(argv[0], iter->name)) { + setprogname(argv[0]); iter->fn(argc, argv); exit(0); } @@ -117,25 +109,22 @@ void run_args(int argc, char **argv, struct redir *redir) { execp(argv); if (errno == EINVAL) { - eprintf("%s isn't a valid executable\n", argv[0]); + errx(1, "%s isn't a valid executable", argv[0]); } else { - eprintf("unknown command: %s\n", argv[0]); + errx(1, "unknown command: %s", argv[0]); } - exit(0); /* kills the subprocess */ } static void run(char *cmd) { - #define ARGV_MAX 16 +#define ARGV_MAX 16 char *argv[ARGV_MAX]; struct redir redir; - int argc = parse(cmd, argv, ARGV_MAX, &redir); if (argc < 0) { - eprintf("error parsing command"); - return; + warn("parsing error"); + } else { + run_args(argc, argv, &redir); } - - run_args(argc, argv, &redir); } @@ -146,16 +135,18 @@ int main(int argc, char **argv) { if (argc > 1) { f = fopen(argv[1], "r"); if (!f) { - eprintf("couldn't open %s\n", argv[1]); + err(1, "couldn't open %s", argv[1]); return 1; } } for (;;) { - if (f == stdin) + if (f == stdin) { printf("%s $ ", getcwd(buf, sizeof buf)); - if (!fgets(buf, 256, f)) + } + if (!fgets(buf, 256, f)) { return 0; + } run(buf); } } diff --git a/src/user/app/shell/shell.h b/src/user/app/shell/shell.h index a8f0012..050e704 100644 --- a/src/user/app/shell/shell.h +++ b/src/user/app/shell/shell.h @@ -2,8 +2,6 @@ #include <stdbool.h> #include <stddef.h> -#define eprintf(fmt, ...) fprintf(stderr, "sh: "fmt"\n" __VA_OPT__(,) __VA_ARGS__) - struct redir { const char *stdout; bool append; diff --git a/src/user/lib/err.c b/src/user/lib/err.c index 7684b6d..7a220fe 100644 --- a/src/user/lib/err.c +++ b/src/user/lib/err.c @@ -20,6 +20,20 @@ _Noreturn void errx(int ret, const char *fmt, ...) { exit(ret); } +void warn(const char *fmt, ...) { + va_list args; + va_start(args, fmt); + vwarn(fmt, args); + va_end(args); +} + +void warnx(const char *fmt, ...) { + va_list args; + va_start(args, fmt); + vwarnx(fmt, args); + va_end(args); +} + void vwarn(const char *fmt, va_list args) { fprintf(stderr, "%s: ", getprogname()); if (fmt) { diff --git a/src/user/lib/include/err.h b/src/user/lib/include/err.h index 9ce4253..6b63c6c 100644 --- a/src/user/lib/include/err.h +++ b/src/user/lib/include/err.h @@ -3,6 +3,8 @@ _Noreturn void err(int ret, const char *fmt, ...); _Noreturn void errx(int ret, const char *fmt, ...); +void warn(const char *fmt, ...); +void warnx(const char *fmt, ...); void vwarn(const char *fmt, va_list args); void vwarnx(const char *fmt, va_list args); |