From 548506392b789f58b1556a6ffca917441e1d89fd Mon Sep 17 00:00:00 2001 From: Jon Santmyer Date: Tue, 13 Oct 2026 22:31:43 -0400 Subject: ipc functions. work on process spawning --- sys/syscall_objdir.c | 95 +++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 94 insertions(+), 1 deletion(-) (limited to 'sys/syscall_objdir.c') diff --git a/sys/syscall_objdir.c b/sys/syscall_objdir.c index 9243af1..199cbab 100644 --- a/sys/syscall_objdir.c +++ b/sys/syscall_objdir.c @@ -2,6 +2,7 @@ #include "proc/process.h" #include "jove.h" #include "lib/printf.h" +#include "sys/objdir.h" #include "syscall.h" int @@ -16,7 +17,7 @@ s_syscall_objdir_objtype( uint16_t local_idx = *((uint16_t*)payload_data); - if(local_idx > JOVE_OBJDIR_ENTRIES) { + if(local_idx > OBJDIR_ENTRIES) { kprintf("%s: Object index is out of bounds (>= 512)\n", __func__); return EOOB; } @@ -25,6 +26,85 @@ s_syscall_objdir_objtype( return obj_peektype(local_obj); } +static int +s_syscall_objdir_swap(jove_owned_obj_t *target_obj, + lockstack_t *lockstack, + jove_owned_obj_t *rootdir, + size_t bytes_left, + void *payload_data) +{ + size_t bytes_needed = sizeof(struct syscall_objdir_swap); + CHECK_TOOSMALL(bytes_needed, bytes_left, "Message too small for payload."); + + struct syscall_objdir_swap *payload = payload_data; + bytes_needed += payload->other_path_length * sizeof(objpath_part_t); + CHECK_TOOSMALL(bytes_needed, bytes_left, "Message too small for other path."); + + jove_owned_obj_t *obj_a = lockstack_push(lockstack, objdir_trygetlocal(target_obj, payload->index)); + if(obj_a == NULL) { + klogf("Getting local object %i failed : %s\n", + payload->index, errstr(errno)); + return -errno; + } + jove_perm_obj_t objdir_b = link_try_traverse_objdir(rootdir, lockstack, + payload->other_path_length - 1, payload->other_path); + if(objdir_b.obj == NULL) { + klogf("Getting object %P failed : %s\n", + payload->other_path, payload->other_path_length, errstr(errno)); + return -errno; + } + + CHECK_OBJPERM(objdir_b, SYSCALL_PERM_OBJDIR_SWAP_TGT, "Other object is missing permission"); + jove_owned_obj_t *obj_b = lockstack_push(lockstack, + objdir_trygetlocal(objdir_b.obj, payload->other_path[payload->other_path_length-1])); + if(obj_b == NULL) { + klogf("Getting object %P failed : %s\n", + payload->other_path, payload->other_path_length, errstr(errno)); + return -errno; + } + + objdir_swapobj(obj_a, obj_b); + return 0; +} + +static int +s_syscall_objdir_link(jove_owned_obj_t *target_obj, + lockstack_t *lockstack, + jove_owned_obj_t *rootdir_obj, + size_t bytes_left, + void *payload_data) +{ + size_t bytes_needed = sizeof(struct syscall_objdir_link); + CHECK_TOOSMALL(bytes_needed, bytes_left, "Message too small for payload"); + + struct syscall_objdir_link *payload = payload_data; + bytes_needed += payload->other_path_length * sizeof(objpath_part_t); + CHECK_TOOSMALL(bytes_needed, bytes_left, "Message too small for other object"); + + jove_owned_obj_t *link_obj = lockstack_push(lockstack, objdir_trygetlocal(target_obj, payload->index)); + if(link_obj == NULL) { + klogf("Getting local object %i failed : %s\n", payload->index, errstr(errno)); + return -errno; + } + CHECK_OBJTYPE(link_obj, JOVE_OBJ_LINK, "Local object is not a link object"); + + jove_perm_obj_t dest_obj = link_try_traverse_objdir(rootdir_obj, lockstack, + payload->other_path_length, payload->other_path); + if(dest_obj.obj == NULL) { + klogf("Getting destination object %P failed : %s\n", + payload->other_path, payload->other_path_length, errstr(errno)); + return -errno; + } + + if(obj_gettype(dest_obj.obj) != JOVE_OBJ_NONE) { + klogf("Destination object %P is not empty\n", + payload->other_path, payload->other_path_length); + return -EFULL; + } + CHECK_OBJPERM(dest_obj, SYSCALL_PERM_OBJDIR_LINK_TGT, "Destination object is missing permissions"); + return link_dup(link_obj, dest_obj.obj); +} + int _syscall_handle_objdir(syscall_context_t *ctx) { @@ -34,6 +114,19 @@ _syscall_handle_objdir(syscall_context_t *ctx) return s_syscall_objdir_objtype( ctx->objdir, ctx->target.obj, ctx->bytes_left, ctx->payload); return -EPERM; + + case SYSCALL_OBJDIR_SWAP: + if(ctx->target.permissions & SYSCALL_PERM_OBJDIR_SWAP) + return s_syscall_objdir_swap(ctx->target.obj, + &ctx->lockstack, ctx->objdir, ctx->bytes_left, ctx->payload); + return -EPERM; + + case SYSCALL_OBJDIR_LINK: + if(ctx->target.permissions & SYSCALL_PERM_OBJDIR_LINK) + return s_syscall_objdir_link(ctx->target.obj, + &ctx->lockstack, ctx->objdir, ctx->bytes_left, ctx->payload); + return -EPERM; + default: return -EBADCALL; } -- cgit v1.2.3