summaryrefslogtreecommitdiff
path: root/src/user
diff options
context:
space:
mode:
authordzwdz2022-12-27 22:42:06 +0100
committerdzwdz2022-12-27 22:42:06 +0100
commit8ac68ecab5734d5c5f3638397e5a9e6084fe7737 (patch)
tree209fcf07d7d4c5f3555a3f78800ba86bd91482c7 /src/user
parent35a82cb0dae43eb538de7afa1da77c4e249ba4e4 (diff)
sh: minor usability / aesthetic improvements
Diffstat (limited to 'src/user')
-rw-r--r--src/user/app/init/init.c3
-rw-r--r--src/user/app/shell/builtins.c42
-rw-r--r--src/user/app/shell/shell.c69
-rw-r--r--src/user/app/shell/shell.h2
-rw-r--r--src/user/lib/err.c14
-rw-r--r--src/user/lib/include/err.h2
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);