summaryrefslogtreecommitdiff
path: root/src/init
diff options
context:
space:
mode:
authordzwdz2022-06-29 23:07:21 +0200
committerdzwdz2022-06-29 23:07:21 +0200
commitbf4f2bb63ed01026b1078f5f7ebfc005bb4bf6d3 (patch)
tree4b1abbcff1db9589709470918b3e75a73ed30341 /src/init
parentbf4cbc830d78774ac00d9501c45e8b84d0ae9ae7 (diff)
init/fs: tmpfs driver with support for creating new files
Diffstat (limited to 'src/init')
-rw-r--r--src/init/driver/driver.h1
-rw-r--r--src/init/driver/tmpfs.c92
-rw-r--r--src/init/main.c1
-rw-r--r--src/init/tar.c1
4 files changed, 95 insertions, 0 deletions
diff --git a/src/init/driver/driver.h b/src/init/driver/driver.h
index dc21573..69c4529 100644
--- a/src/init/driver/driver.h
+++ b/src/init/driver/driver.h
@@ -2,3 +2,4 @@
void ansiterm_drv(void);
void ps2_drv(void);
+void tmpfs_drv(void);
diff --git a/src/init/driver/tmpfs.c b/src/init/driver/tmpfs.c
new file mode 100644
index 0000000..17b5b9b
--- /dev/null
+++ b/src/init/driver/tmpfs.c
@@ -0,0 +1,92 @@
+#include <init/malloc.h>
+#include <shared/mem.h>
+#include <shared/syscalls.h>
+#include <stddef.h>
+
+struct node {
+ const char *name;
+ size_t len;
+ struct node *next;
+};
+
+struct node *root = NULL;
+
+static struct node *lookup(const char *path, size_t len) {
+ for (struct node *iter = root; iter; iter = iter->next) {
+ if (iter->len == len && !memcmp(path, iter->name, len))
+ return iter;
+ }
+ return NULL;
+}
+
+static int tmpfs_open(const char *path, struct fs_wait_response *res) {
+ if (res->len == 0) return -1;
+ path++;
+ res->len--;
+
+ if (res->len == 0) return 0; /* root */
+
+ // no directory support (yet)
+ if (memchr(path, '/', res->len)) return -1;
+
+ if (res->flags & OPEN_CREATE) {
+ if (lookup(path, res->len)) return -1; /* already exists */
+ struct node *new = malloc(sizeof *new);
+ char *namebuf = malloc(res->len);
+ memcpy(namebuf, path, res->len);
+ new->name = namebuf;
+ new->len = res->len;
+ new->next = root;
+ root = new;
+ return 1;
+ }
+
+ return lookup(path, res->len) != 0 ? 1 : -1;
+}
+
+void tmpfs_drv(void) {
+ // TODO replace all the static allocations in drivers with mallocs
+ static char buf[512];
+ struct fs_wait_response res;
+ while (!_syscall_fs_wait(buf, sizeof buf, &res)) {
+ switch (res.op) {
+ case VFSOP_OPEN:
+ _syscall_fs_respond(NULL, tmpfs_open(buf, &res));
+ break;
+
+ case VFSOP_READ:
+ if (res.id != 0) {
+ // rw unimplemented
+ _syscall_fs_respond(NULL, -1);
+ break;
+ }
+ size_t buf_pos = 0;
+ size_t to_skip = res.offset;
+
+ for (struct node *iter = root; iter; iter = iter->next) {
+ if (iter->len <= to_skip) {
+ to_skip -= iter->len;
+ continue;
+ }
+
+ if (iter->len + buf_pos - to_skip >= sizeof(buf)) {
+ memcpy(buf + buf_pos, iter->name + to_skip, sizeof(buf) - buf_pos - to_skip);
+ buf_pos = sizeof(buf);
+ break;
+ }
+ memcpy(buf + buf_pos, iter->name + to_skip, iter->len - to_skip);
+ buf_pos += iter->len - to_skip;
+ buf[buf_pos++] = '\0';
+ to_skip = 0;
+ }
+ _syscall_fs_respond(buf, buf_pos);
+ break;
+
+ default:
+ _syscall_fs_respond(NULL, -1);
+ break;
+ }
+ }
+
+ _syscall_exit(1);
+}
diff --git a/src/init/main.c b/src/init/main.c
index 198bd88..9afb2a7 100644
--- a/src/init/main.c
+++ b/src/init/main.c
@@ -23,6 +23,7 @@ int main(void) {
printf("preinit\n");
MOUNT("/init/", tar_driver(&_initrd));
+ MOUNT("/tmp/", tmpfs_drv());
MOUNT("/keyboard", ps2_drv());
MOUNT("/vga_tty", ansiterm_drv());
diff --git a/src/init/tar.c b/src/init/tar.c
index ce8c066..0b8c7f6 100644
--- a/src/init/tar.c
+++ b/src/init/tar.c
@@ -55,6 +55,7 @@ static int tar_open(const char *path, int len, void *base, size_t base_len) {
ptr = tar_find(path, len, base, base_len);
if (!ptr) return -1;
+ // TODO this won't work if ptr > 0x80000000
return (int)ptr;
}