summaryrefslogtreecommitdiff
path: root/src/user/app/init/init.c
blob: bb92ccecac63e5022848a3562c3eb7944c02e631 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
#include "driver/driver.h"
#include <camellia/flags.h>
#include <camellia/syscalls.h>
#include <stdint.h>
#include <stdio.h>
#include <unistd.h>
#include <user/lib/fs/misc.h>

#define die(fmt, ...) do { fprintf(stderr, "init: " fmt, __VA_ARGS__); exit(1); } while (0)

void redirect(const char *exe, const char *out, const char *in) {
	if (!fork()) {
		if (!freopen(out, "a+", stderr)) {
			fprintf(stdout, "couldn't open %s\n", out);
			exit(1);
		}
		if (!freopen(out, "a+", stdout))
			die("couldn't open %s\n", out);
		if (!freopen(in, "r", stdin))
			die(" couldn't open %s\n", in);
		termcook();
		execv(exe, NULL);
		die("couldn't start %s\n", exe);
	}
}

int main(void) {
	freopen("/kdev/com1", "a+", stdout);
	printf("in init (stage 2), main at 0x%x\n", &main);

	MOUNT("/tmp/", tmpfs_drv());
	MOUNT("/keyboard", ps2_drv());
	MOUNT("/vga_tty", ansiterm_drv());
	MOUNT("/bin/", fs_passthru("/init/bin"));

	if (fork()) {
		/* used to trigger a kernel bug
		 * 7c96f9c03502e0c60f23f4c550d12a629f3b3daf */
		_syscall_await();
		exit(1);
	}

	redirect("/bin/shell", "/kdev/com1", "/kdev/com1");
	redirect("/bin/shell", "/vga_tty", "/keyboard");

	_syscall_await();
	printf("init: quitting\n");
	return 0;
}