summaryrefslogtreecommitdiff
path: root/src/cmd/init/init.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd/init/init.c')
-rw-r--r--src/cmd/init/init.c44
1 files changed, 36 insertions, 8 deletions
diff --git a/src/cmd/init/init.c b/src/cmd/init/init.c
index 5c49281..d8cb1f4 100644
--- a/src/cmd/init/init.c
+++ b/src/cmd/init/init.c
@@ -1,4 +1,5 @@
#include "driver/driver.h"
+#include <camellia.h>
#include <camellia/compat.h>
#include <camellia/flags.h>
#include <camellia/fs/misc.h>
@@ -12,9 +13,9 @@
void redirect(const char *exe, const char *out, const char *in) {
if (!fork()) {
- static char title[128];
- snprintf(title, sizeof title, "sh >%s", out);
- setproctitle(title);
+ static char buf[128];
+ snprintf(buf, sizeof buf, "sh >%s", out);
+ setproctitle(buf);
if (!freopen(out, "a+", stderr)) {
fprintf(stdout, "couldn't open %s\n", out);
@@ -25,17 +26,44 @@ void redirect(const char *exe, const char *out, const char *in) {
if (!freopen(in, "r", stdin))
err(1, "couldn't open %s", in);
+ // TODO move to /dev/term/
+ MOUNT_AT("/") {
+ fs_dirinject2((const char*[]){ "/term/", NULL });
+ }
+ MOUNT_AT("/term/") {
+ termcook();
+ }
+ int fd = camellia_open("/term/stdin", OPEN_READ);
+ if (fd < 0) {
+ err(1, "open /term/stdin");
+ }
+ _sys_dup(fd, 0, 0);
+ close(fd);
+
for (;;) {
- if (!fork()) {
+ int pid = fork();
+ if (pid == 0) {
+ // TODO shadow over /term/tokill, as it's an easy thing to miss when sandboxing
const char *argv[] = {exe, NULL};
- termcook();
execv(exe, (void*)argv);
fprintf(stderr, "init: couldn't start %s\n", exe);
exit(1);
+ } else {
+ int len, fd;
+ fd = camellia_open("/term/tokill", OPEN_WRITE);
+ if (fd < 0) {
+ _sys_intr("kill", 4);
+ err(1, "open /term/tokill");
+ }
+ len = snprintf(buf, sizeof buf, "/proc/%d/intrdown", pid);
+ _sys_write(fd, buf, len, 0, 0);
+ len = snprintf(buf, sizeof buf, "/proc/%d/intr", pid);
+ _sys_write(fd, buf, len, 0, 0);
+ close(fd);
+
+ _sys_await();
+ _sys_sleep(1000);
}
- _sys_await();
- _sys_intr(NULL, 0);
- _sys_sleep(1000);
}
}
}