summaryrefslogtreecommitdiff
path: root/src/init
diff options
context:
space:
mode:
Diffstat (limited to 'src/init')
-rw-r--r--src/init/main.c50
-rw-r--r--src/init/stdlib.c53
-rw-r--r--src/init/stdlib.h4
-rw-r--r--src/init/syscalls.c8
4 files changed, 89 insertions, 26 deletions
diff --git a/src/init/main.c b/src/init/main.c
index 5c798d2..401e4a0 100644
--- a/src/init/main.c
+++ b/src/init/main.c
@@ -1,10 +1,10 @@
+#include <init/stdlib.h>
#include <init/tar.h>
#include <shared/flags.h>
#include <shared/syscalls.h>
#include <stdint.h>
#define argify(str) str, sizeof(str) - 1
-#define log(str) _syscall_write(tty_fd, argify(str), 0)
extern char _bss_start; // provided by the linker
extern char _bss_end;
@@ -23,7 +23,7 @@ int main(void) {
tty_fd = _syscall_open("/tty", sizeof("/tty") - 1);
if (tty_fd < 0)
- _syscall_exit(argify("couldn't open tty"));
+ _syscall_exit(1);
fs_test();
test_await();
@@ -32,7 +32,7 @@ int main(void) {
while (_syscall_read(tty_fd, &c, 1, 0))
_syscall_write(tty_fd, &c, 1, 0);
- _syscall_exit(argify("my job here is done."));
+ _syscall_exit(0);
}
void read_file(const char *path, size_t len) {
@@ -41,9 +41,9 @@ void read_file(const char *path, size_t len) {
int buf_len = 64;
_syscall_write(tty_fd, path, len, 0);
- log(": ");
+ printf(": ");
if (fd < 0) {
- log("couldn't open.\n");
+ printf("couldn't open.\n");
return;
}
@@ -64,7 +64,7 @@ void fs_test(void) {
}
// parent: accesses the fs
- log("\n\n");
+ printf("\n\n");
// the trailing slash should be ignored by mount()
_syscall_mount(front, argify("/init/"));
read_file(argify("/init/fake.txt"));
@@ -72,30 +72,36 @@ void fs_test(void) {
read_file(argify("/init/2.txt"));
read_file(argify("/init/dir/3.txt"));
- log("\nshadowing /init/dir...\n");
+ printf("\nshadowing /init/dir...\n");
_syscall_mount(-1, argify("/init/dir"));
read_file(argify("/init/fake.txt"));
read_file(argify("/init/1.txt"));
read_file(argify("/init/2.txt"));
read_file(argify("/init/dir/3.txt"));
- log("\n");
+ printf("\n");
}
void test_await(void) {
- char buf[16];
- int len;
-
- // the child immediately dies
- if (!_syscall_fork())
- _syscall_exit(argify("i'm dead"));
- if (!_syscall_fork())
- _syscall_exit(argify("i'm also dead"));
-
- while ((len = _syscall_await(buf, 16)) >= 0) {
- log("await returned: ");
- _syscall_write(tty_fd, buf, len, 0);
- log("\n");
+ int ret;
+
+ // regular exit()s
+ if (!_syscall_fork()) _syscall_exit(69);
+ if (!_syscall_fork()) _syscall_exit(420);
+
+ // faults
+ if (!_syscall_fork()) { // invalid memory access
+ asm volatile("movb $69, 0" ::: "memory");
+ printf("this shouldn't happen");
+ _syscall_exit(-1);
}
- log("await: negative len\n");
+ if (!_syscall_fork()) { // #GP
+ asm volatile("hlt" ::: "memory");
+ printf("this shouldn't happen");
+ _syscall_exit(-1);
+ }
+
+ while ((ret = _syscall_await()) != ~0)
+ printf("await returned: %x\n", ret);
+ printf("await: no more children\n");
}
diff --git a/src/init/stdlib.c b/src/init/stdlib.c
index 6ed5a0a..a60854b 100644
--- a/src/init/stdlib.c
+++ b/src/init/stdlib.c
@@ -1,4 +1,6 @@
#include <init/stdlib.h>
+#include <shared/syscalls.h>
+#include <stdarg.h>
int memcmp(const void *s1, const void *s2, size_t n) {
const unsigned char *c1 = s1, *c2 = s2;
@@ -10,3 +12,54 @@ int memcmp(const void *s1, const void *s2, size_t n) {
}
return 0;
}
+
+size_t strlen(const char *s) {
+ size_t c = 0;
+ while (*s++) c++;
+ return c;
+}
+
+int printf(const char *fmt, ...) {
+ const char *seg = fmt; // beginning of the current segment
+ int total = 0;
+ va_list argp;
+ va_start(argp, fmt);
+ for (;;) {
+ char c = *fmt++;
+ switch (c) {
+ case '\0':
+ // TODO don't assume that stdout is @ fd 0
+ _syscall_write(0, seg, fmt - seg - 1, 0);
+ return total + (fmt - seg - 1);
+
+ case '%':
+ _syscall_write(0, seg, fmt - seg - 1, 0);
+ total += fmt - seg - 1;
+ c = *fmt++;
+ switch (c) {
+ case 's':
+ const char *s = va_arg(argp, char*);
+ _syscall_write(0, s, strlen(s), 0);
+ total += strlen(s);
+ break;
+
+ case 'x':
+ unsigned int n = va_arg(argp, int);
+ size_t i = 4; // nibbles * 4
+ while (n >> i && i < (sizeof(int) * 8))
+ i += 4;
+
+ while (i > 0) {
+ i -= 4;
+ char h = '0' + ((n >> i) & 0xf);
+ if (h > '9') h += 'a' - '9' - 1;
+ _syscall_write(0, &h, 1, 0);
+ total++;
+ }
+ break;
+ }
+ seg = fmt;
+ break;
+ }
+ }
+}
diff --git a/src/init/stdlib.h b/src/init/stdlib.h
index 1cabc7a..3e56beb 100644
--- a/src/init/stdlib.h
+++ b/src/init/stdlib.h
@@ -5,3 +5,7 @@
// stb-style header file
int memcmp(const void *s1, const void *s2, size_t n);
+
+size_t strlen(const char *s);
+
+int printf(const char *fmt, ...);
diff --git a/src/init/syscalls.c b/src/init/syscalls.c
index f32594e..57a7344 100644
--- a/src/init/syscalls.c
+++ b/src/init/syscalls.c
@@ -1,8 +1,8 @@
// this file could probably just get generated by a script
#include <shared/syscalls.h>
-_Noreturn void _syscall_exit(const char __user *msg, size_t len) {
- _syscall(_SYSCALL_EXIT, (int)msg, len, 0, 0);
+_Noreturn void _syscall_exit(int ret) {
+ _syscall(_SYSCALL_EXIT, ret, 0, 0, 0);
__builtin_unreachable();
}
@@ -10,8 +10,8 @@ int _syscall_fork(void) {
return _syscall(_SYSCALL_FORK, 0, 0, 0, 0);
}
-int _syscall_await(char __user *buf, int len) {
- return _syscall(_SYSCALL_AWAIT, (int)buf, (int)len, 0, 0);
+int _syscall_await(void) {
+ return _syscall(_SYSCALL_AWAIT, 0, 0, 0, 0);
}
handle_t _syscall_open(const char __user *path, int len) {