diff options
Diffstat (limited to 'src/init')
-rw-r--r-- | src/init/main.c | 50 | ||||
-rw-r--r-- | src/init/stdlib.c | 53 | ||||
-rw-r--r-- | src/init/stdlib.h | 4 | ||||
-rw-r--r-- | src/init/syscalls.c | 8 |
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) { |