diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/user/app/init/init.c | 4 | ||||
-rw-r--r-- | src/user/app/ps/ps.c | 73 | ||||
-rw-r--r-- | src/user/bootstrap/linker.ld | 2 | ||||
-rw-r--r-- | src/user/bootstrap/main.c | 8 | ||||
-rw-r--r-- | src/user/lib/_start2.c | 11 | ||||
-rw-r--r-- | src/user/lib/elfload.c | 2 | ||||
-rw-r--r-- | src/user/lib/fs/misc.c | 2 | ||||
-rw-r--r-- | src/user/lib/include/_proc.h | 7 | ||||
-rw-r--r-- | src/user/lib/include/stdlib.h | 1 | ||||
-rw-r--r-- | src/user/lib/stdlib.c | 14 |
10 files changed, 118 insertions, 6 deletions
diff --git a/src/user/app/init/init.c b/src/user/app/init/init.c index 73e863e..d872b24 100644 --- a/src/user/app/init/init.c +++ b/src/user/app/init/init.c @@ -41,7 +41,7 @@ int main(void) { freopen("/kdev/com1", "a+", stdout); freopen("/kdev/com1", "a+", stderr); - printf("[init] stage 2, main at %p, testtr at %p\n", &main, teststr); + printf("[init] stage 2, main at %p, teststr at %p\n", &main, teststr); MOUNT_AT("/keyboard") { MOUNT_AT("/") { fs_whitelist((const char*[]){"/kdev/ps2/kb", NULL}); } @@ -101,8 +101,6 @@ int main(void) { close(killswitch_pipe[0]); redirect("/bin/shell", "/kdev/com1", "/kdev/com1"); redirect("/bin/shell", "/vtty", "/keyboard"); - // TODO busy loop without no children - for (;;) _syscall_await(); exit(1); } diff --git a/src/user/app/ps/ps.c b/src/user/app/ps/ps.c new file mode 100644 index 0000000..78d4204 --- /dev/null +++ b/src/user/app/ps/ps.c @@ -0,0 +1,73 @@ +#include <_proc.h> +#include <ctype.h> +#include <err.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +/* returns a pointer that can be set to NUL to undo the strcat */ +static char * +strtcat(char *dst, const char *src) +{ + char *s = dst + strlen(dst); + strcpy(s, src); + return s; +} + +static void +do_proc(char *path) +{ + const int bufl = 4096; + char *buf = malloc(bufl); + FILE *f; + + { /* read the psdata into buf */ + char *s = strtcat(path, "mem"); + f = fopen(path, "r"); + *s = '\0'; + if (!f) errx(1, "couldn't open '%s'", path); + fseek(f, (long)_libc_psdata, SEEK_SET); + if (fread(buf, 1, 128, f) <= 0) { + strcpy(buf, "(no psdata)"); + } + buf[128] = '\0'; + fclose(f); + } + + printf("%20s %s\n", path, buf); + + f = fopen(path, "r"); + if (!f) errx(1, "couldn't open '%s'", path); + + // TODO library for iterating over directories + for (;;) { + int len = fread(buf, 1, bufl, f); + if (len <= 0) break; + for (int pos = 0; pos < len; ) { + const char *end = memchr(buf + pos, 0, len - pos); + if (!end) { + errx(1, "unimplemented: buffer overflow"); + } + size_t entryl = end - (buf + pos) + 1; + if (isdigit(buf[pos])) { + /* yup, no overflow check */ + char *s = strtcat(path, buf + pos); + do_proc(path); + *s = '\0'; + } + pos += entryl; + } + } + + free(buf); + fclose(f); +} + +int +main(void) +{ + char *buf = malloc(4096); + strcpy(buf, "/proc/"); + do_proc(buf); + return 0; +} diff --git a/src/user/bootstrap/linker.ld b/src/user/bootstrap/linker.ld index f2d718f..34d8101 100644 --- a/src/user/bootstrap/linker.ld +++ b/src/user/bootstrap/linker.ld @@ -3,7 +3,7 @@ OUTPUT_FORMAT("binary") SECTIONS { - . = 0x10000; + . = 0x20000; _bss_start = .; .bss BLOCK(4K) : ALIGN(4K) { diff --git a/src/user/bootstrap/main.c b/src/user/bootstrap/main.c index f145e74..577f1d8 100644 --- a/src/user/bootstrap/main.c +++ b/src/user/bootstrap/main.c @@ -1,3 +1,4 @@ +#include <_proc.h> #include <camellia/flags.h> #include <camellia/syscalls.h> #include <stdio.h> @@ -13,6 +14,10 @@ extern char _initrd; __attribute__((section(".text"))) _Noreturn void main(void) { + _syscall_memflag(_libc_psdata, 1, MEMFLAG_PRESENT); + setprogname("bootstrap"); + setproctitle(NULL); + /* move everything provided by the kernel to /kdev */ MOUNT_AT("/kdev/") { fs_passthru(NULL); } MOUNT_AT("/") { @@ -26,10 +31,11 @@ _Noreturn void main(void) { MOUNT_AT("/init/") { tar_driver(&_initrd); } const char *initpath = "bin/amd64/init"; + char *initargv[] = {"init", NULL}; void *init = tar_find(initpath, strlen(initpath), &_initrd, ~0) + 512; if (init) { _klogf("execing init"); - elf_exec(init, NULL, NULL); + elf_exec(init, initargv, NULL); _klogf("elf_exec failed"); } else { _klogf("couldn't find init.elf"); diff --git a/src/user/lib/_start2.c b/src/user/lib/_start2.c index 495f046..2cf8667 100644 --- a/src/user/lib/_start2.c +++ b/src/user/lib/_start2.c @@ -1,3 +1,5 @@ +#include <_proc.h> +#include <camellia/flags.h> #include <camellia/syscalls.h> #include <stdio.h> #include <stdlib.h> @@ -22,6 +24,15 @@ void intr_trampoline(void); /* intr.s */ _Noreturn void _start2(struct execdata *ed) { const char *progname; elf_selfreloc(); + + /* done first so it isn't allocated elsewhere by accident */ + _syscall_memflag(_libc_psdata, 1, MEMFLAG_PRESENT); + if (ed->argv[0]) { + strcpy(_libc_psdata, ed->argv[0]); + } else { + strcpy(_libc_psdata, "?"); + } + _syscall_intr_set(intr_trampoline); intr_set(intr_default); __setinitialcwd(ed->cwd); diff --git a/src/user/lib/elfload.c b/src/user/lib/elfload.c index 7cad10f..a4ee91e 100644 --- a/src/user/lib/elfload.c +++ b/src/user/lib/elfload.c @@ -160,7 +160,7 @@ void elf_exec(void *base, char **argv, char **envp) { void *exebase = elf_loadmem(ehdr); if (!exebase) return; - void *newstack = _syscall_memflag((void*)0x1000, 0x1000, MEMFLAG_FINDFREE | MEMFLAG_PRESENT); + void *newstack = _syscall_memflag((void*)0x11000, 0x1000, MEMFLAG_FINDFREE | MEMFLAG_PRESENT); if (!newstack) return; _freejmp_chstack(exebase + ehdr->e_entry, exebase, elf_spread(ehdr) + 0x1000, (const char**)argv, envp, newstack); diff --git a/src/user/lib/fs/misc.c b/src/user/lib/fs/misc.c index 11428b8..ee0b54c 100644 --- a/src/user/lib/fs/misc.c +++ b/src/user/lib/fs/misc.c @@ -233,11 +233,13 @@ bool mount_at_pred(const char *path) { if (!fork2_n_mount(path)) { /* child -> go into the for body */ _klogf("%s: impl", path); + setproctitle("i'%s'", path); return true; } if (strcmp("/", path) && !fork2_n_mount("/")) { _klogf("%s: dir", path); + setproctitle("d'%s'", path); fs_dir_inject(path); exit(1); } diff --git a/src/user/lib/include/_proc.h b/src/user/lib/include/_proc.h new file mode 100644 index 0000000..c8fd70b --- /dev/null +++ b/src/user/lib/include/_proc.h @@ -0,0 +1,7 @@ +#pragma once + +/* That page contains a null-terminated string that describes the process + * for tools such as ps. It's first allocated in the bootstrap process, and + * then it's freed on every exec() - just to be immediately reallocated by + * _start2(). */ +static char *const _libc_psdata = (void*)0x10000; diff --git a/src/user/lib/include/stdlib.h b/src/user/lib/include/stdlib.h index 8a86265..050ca80 100644 --- a/src/user/lib/include/stdlib.h +++ b/src/user/lib/include/stdlib.h @@ -14,6 +14,7 @@ _Noreturn void exit(int); const char *getprogname(void); void setprogname(const char *progname); +void setproctitle(const char *fmt, ...); int mkstemp(char *template); char *getenv(const char *name); diff --git a/src/user/lib/stdlib.c b/src/user/lib/stdlib.c index 5d1b09f..4e471ba 100644 --- a/src/user/lib/stdlib.c +++ b/src/user/lib/stdlib.c @@ -1,3 +1,4 @@ +#include <_proc.h> #include <camellia.h> #include <camellia/syscalls.h> #include <errno.h> @@ -16,6 +17,19 @@ void setprogname(const char *pg) { progname = pg; } +void setproctitle(const char *fmt, ...) { + if (!fmt) { + strcpy(_libc_psdata, progname); + return; + } + sprintf(_libc_psdata, "%s: ", progname); + + va_list argp; + va_start(argp, fmt); + vsnprintf(_libc_psdata + strlen(_libc_psdata), 128, fmt, argp); + va_end(argp); +} + int mkstemp(char *template) { // TODO randomize template handle_t h = camellia_open(template, OPEN_CREATE | OPEN_RW); |