summaryrefslogtreecommitdiff
path: root/src/init
diff options
context:
space:
mode:
authordzwdz2022-05-02 18:43:49 +0200
committerdzwdz2022-05-02 18:43:49 +0200
commit8513ae3c3e83ec8835bc0d1355284a9ddd928693 (patch)
treee5acf926b8bb3ad6a7660cb4ea5f7500c9255fb1 /src/init
parent5abfbff30588e70efb5fc414f32b4bbda333f3f8 (diff)
kernel/vfs: pass `close()` calls to fs handlers
Diffstat (limited to 'src/init')
-rw-r--r--src/init/fs/misc.c36
-rw-r--r--src/init/tests/main.c2
2 files changed, 30 insertions, 8 deletions
diff --git a/src/init/fs/misc.c b/src/init/fs/misc.c
index 64e3664..53373f4 100644
--- a/src/init/fs/misc.c
+++ b/src/init/fs/misc.c
@@ -3,6 +3,7 @@
#include <shared/flags.h>
#include <shared/mem.h>
#include <shared/syscalls.h>
+#include <stdbool.h>
bool fork2_n_mount(const char *path) {
handle_t h = _syscall_fs_fork2();
@@ -70,6 +71,12 @@ static void fs_respond_delegate(struct fs_wait_response *res, handle_t delegate,
_syscall_fs_respond(NULL, ret);
break;
+ case VFSOP_CLOSE:
+ _syscall_close(delegate);
+ _syscall_fs_respond(NULL, 0);
+ // isn't it kinda weird that i even have to respond to close()s?
+ // i suppose it makes the API more consistent
+
default:
/* unsupported / unexpected */
_syscall_fs_respond(NULL, -1);
@@ -113,34 +120,49 @@ void fs_passthru(const char *prefix) {
void fs_dir_inject(const char *path) {
struct fs_dir_handle {
+ bool taken;
int delegate;
const char *inject;
};
const size_t path_len = strlen(path);
struct fs_wait_response res;
- struct fs_dir_handle handles[16]; // TODO hardcoded FD_MAX - use malloc instead
- int handle_next = 0;
+ struct fs_dir_handle handles[16] = {0}; // TODO hardcoded FD_MAX - use malloc instead
static char buf[1024];
int ret;
while (!_syscall_fs_wait(buf, sizeof buf, &res)) {
switch (res.op) {
case VFSOP_OPEN:
- if (handle_next > 15) _syscall_fs_respond(NULL, -2); // we ran out of handles, which is entirely our fault.
+ int hid = -1;
+ for (int hid2 = 0; hid2 * sizeof(*handles) < sizeof(handles); hid2++) {
+ if (!handles[hid2].taken) {
+ hid = hid2;
+ break;
+ }
+ }
+ if (hid < 0) _syscall_fs_respond(NULL, -2); // we ran out of handles
ret = _syscall_open(buf, res.len); /* errors handled in inject handler */
- handles[handle_next].delegate = ret;
- handles[handle_next].inject = NULL;
+ handles[hid].delegate = ret;
+ handles[hid].inject = NULL;
+ handles[hid].taken = true;
if (buf[res.len - 1] == '/' &&
res.len < path_len && !memcmp(path, buf, res.len)) {
- handles[handle_next].inject = path + res.len;
+ handles[hid].inject = path + res.len;
} else {
/* not injecting, don't allow opening nonexistent stuff */
if (ret < 0) _syscall_fs_respond(NULL, ret);
}
- _syscall_fs_respond(NULL, handle_next++);
+ _syscall_fs_respond(NULL, hid);
+ break;
+
+ case VFSOP_CLOSE:
+ if (handles[res.id].delegate >= 0)
+ _syscall_close(handles[res.id].delegate);
+ handles[res.id].taken = false;
+ _syscall_fs_respond(NULL, 0);
break;
case VFSOP_READ:
diff --git a/src/init/tests/main.c b/src/init/tests/main.c
index ed50229..1c1e817 100644
--- a/src/init/tests/main.c
+++ b/src/init/tests/main.c
@@ -105,5 +105,5 @@ void test_all(void) {
run_forked(test_faults);
run_forked(test_interrupted_fs);
run_forked(test_orphaned_fs);
- run_forked(stress_fork);
+// run_forked(stress_fork);
}