aboutsummaryrefslogtreecommitdiff
path: root/user/sbin/init.c
diff options
context:
space:
mode:
authornthnluu <nate1299@me.com>2024-01-28 21:20:27 -0500
committernthnluu <nate1299@me.com>2024-01-28 21:20:27 -0500
commitc63f340d90800895f007de64b7d2d14624263331 (patch)
tree2c0849fa597dd6da831c8707b6f2603403778d7b /user/sbin/init.c
Created student weenix repository
Diffstat (limited to 'user/sbin/init.c')
-rw-r--r--user/sbin/init.c115
1 files changed, 115 insertions, 0 deletions
diff --git a/user/sbin/init.c b/user/sbin/init.c
new file mode 100644
index 0000000..6bfe6ae
--- /dev/null
+++ b/user/sbin/init.c
@@ -0,0 +1,115 @@
+/*
+ * Forks a shell for each terminal and waits for them.
+ * This is the final thing you should be executing
+ * (with kernel_execve) in kernel-land once everything works.
+ */
+
+#include <dirent.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+char *empty[] = {NULL};
+
+const char *hi = "init: starting shell on ";
+const char *sh = "/bin/sh";
+const char *ttystr = "tty";
+const char *home = "/";
+const char *alldone = "init: no remaining processes\n";
+
+static int open_tty(char *tty)
+{
+ if (-1 == open(tty, O_RDONLY, 0))
+ {
+ return -1;
+ }
+ else if (-1 == open(tty, O_WRONLY, 0))
+ {
+ return -1;
+ }
+ else if (2 != dup(1))
+ {
+ return -1;
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+static int canary = 0x12345678;
+
+static void spawn_shell_on(char *tty)
+{
+ if (!fork())
+ {
+ close(0);
+ close(1);
+ close(2);
+ if (-1 == open_tty(tty))
+ {
+ exit(1);
+ }
+
+ chdir(home);
+
+ printf("%s%s\n", hi, tty);
+
+ execve(sh, empty, empty);
+ fprintf(stderr, "exec failed!\n");
+ }
+}
+
+int main(int argc, char **argv, char **envp)
+{
+ int devdir, ii;
+ dirent_t d;
+ int status;
+
+ for (ii = 0; ii < NFILES; ii++)
+ {
+ close(ii);
+ }
+ ii = ii;
+
+ if (-1 == open_tty("/dev/tty0"))
+ {
+ exit(1);
+ }
+
+ chdir("/dev");
+
+ devdir = open("/dev", O_RDONLY, 0);
+ while (getdents(devdir, &d, sizeof(d)) > 0)
+ {
+ if (0 == strncmp(d.d_name, ttystr, strlen(ttystr)))
+ {
+ spawn_shell_on(d.d_name);
+ }
+ }
+ close(devdir);
+
+ int pid;
+ while (0 <= (pid = wait(&status)))
+ {
+ if (EFAULT == status)
+ {
+ printf("process %i faulted\n", pid);
+ }
+ }
+
+ if (ECHILD != errno)
+ {
+ printf("error: wait: %s\n", strerror(errno));
+ return 1;
+ }
+ else
+ {
+ printf("%s", alldone);
+ return 0;
+ }
+}