diff options
Diffstat (limited to 'src/user/app/init')
-rw-r--r-- | src/user/app/init/driver/tmpfs.c | 132 | ||||
-rw-r--r-- | src/user/app/init/init.c | 5 |
2 files changed, 4 insertions, 133 deletions
diff --git a/src/user/app/init/driver/tmpfs.c b/src/user/app/init/driver/tmpfs.c deleted file mode 100644 index c7abf50..0000000 --- a/src/user/app/init/driver/tmpfs.c +++ /dev/null @@ -1,132 +0,0 @@ -#include <camellia/fsutil.h> -#include <camellia/syscalls.h> -#include <shared/mem.h> -#include <stddef.h> -#include <stdlib.h> -#include <unistd.h> -#include <user/lib/fs/dir.h> - -struct node { - const char *name; - size_t namelen; - struct node *next; - char *buf; - size_t size, capacity; -}; - -struct node *root = NULL; -static struct node special_root = { - .size = 0, -}; - -static struct node *lookup(const char *path, size_t len) { - for (struct node *iter = root; iter; iter = iter->next) { - if (iter->namelen == len && !memcmp(path, iter->name, len)) - return iter; - } - return NULL; -} - -static struct node *tmpfs_open(const char *path, struct fs_wait_response *res) { - struct node *node; - if (res->len == 0) return NULL; - path++; - res->len--; - - if (res->len == 0) return &special_root; - - // no directory support (yet) - if (memchr(path, '/', res->len)) return NULL; - - node = lookup(path, res->len); - if (!node && (res->flags & OPEN_CREATE)) { - node = malloc(sizeof *node); - memset(node, 0, sizeof *node); - - char *namebuf = malloc(res->len + 1); - memcpy(namebuf, path, res->len); - namebuf[res->len] = '\0'; - node->name = namebuf; - node->namelen = res->len; - node->next = root; - root = node; - } - return node; -} - -void tmpfs_drv(void) { - const size_t buflen = 4096; - char *buf = malloc(buflen); - struct fs_wait_response res; - struct node *ptr; - while (!_syscall_fs_wait(buf, buflen, &res)) { - switch (res.op) { - case VFSOP_OPEN: - ptr = tmpfs_open(buf, &res); - _syscall_fs_respond(ptr, ptr ? 0 : -1, 0); - break; - - case VFSOP_READ: - ptr = (void*)res.id; - if (ptr == &special_root) { - struct dirbuild db; - dir_start(&db, res.offset, buf, buflen); - for (struct node *iter = root; iter; iter = iter->next) - dir_append(&db, iter->name); - _syscall_fs_respond(buf, dir_finish(&db), 0); - } else { - fs_normslice(&res.offset, &res.len, ptr->size, false); - _syscall_fs_respond(ptr->buf + res.offset, res.len, 0); - break; - } - break; - - case VFSOP_WRITE: - ptr = (void*)res.id; - if (ptr == &special_root) { - _syscall_fs_respond(NULL, -1, 0); - break; - } - if (res.len > 0 && !ptr->buf) { - ptr->buf = malloc(256); - if (!ptr->buf) { - _syscall_fs_respond(NULL, -1, 0); - break; - } - memset(ptr->buf, 0, 256); - ptr->capacity = 256; - } - - fs_normslice(&res.offset, &res.len, ptr->size, true); - if (ptr->capacity <= res.offset + res.len) { - size_t newcap = 1; - while (newcap && newcap <= res.offset + res.len) - newcap *= 2; - if (!newcap) { /* overflow */ - _syscall_fs_respond(NULL, -1, 0); - break; - } - ptr->capacity = newcap; - ptr->buf = realloc(ptr->buf, ptr->capacity); - } - - memcpy(ptr->buf + res.offset, buf, res.len); - if ((res.flags & WRITE_TRUNCATE) || ptr->size < res.offset + res.len) { - ptr->size = res.offset + res.len; - } - _syscall_fs_respond(NULL, res.len, 0); - break; - - case VFSOP_GETSIZE: - ptr = (void*)res.id; - _syscall_fs_respond(NULL, ptr->size, 0); - break; - - default: - _syscall_fs_respond(NULL, -1, 0); - break; - } - } - - exit(1); -} diff --git a/src/user/app/init/init.c b/src/user/app/init/init.c index 9e7ab7b..f011ca5 100644 --- a/src/user/app/init/init.c +++ b/src/user/app/init/init.c @@ -29,9 +29,12 @@ int main(void) { freopen("/kdev/com1", "a+", stderr); printf("in init (stage 2), main at 0x%x\n", &main); - MOUNT_AT("/tmp/") { tmpfs_drv(); } MOUNT_AT("/keyboard") { ps2_drv(); } MOUNT_AT("/bin/") { fs_passthru("/init/bin"); } + MOUNT_AT("/tmp/") { + const char *argv[] = {"/bin/tmpfs", NULL}; + execv(argv[0], (void*)argv); + } MOUNT_AT("/vtty") { const char *argv[] = {"/bin/vterm", NULL}; execv(argv[0], (void*)argv); |