summaryrefslogtreecommitdiffstats
path: root/syscall/invoke_objdir.c
diff options
context:
space:
mode:
Diffstat (limited to 'syscall/invoke_objdir.c')
-rw-r--r--syscall/invoke_objdir.c94
1 files changed, 79 insertions, 15 deletions
diff --git a/syscall/invoke_objdir.c b/syscall/invoke_objdir.c
index 4698f34..9cd3f32 100644
--- a/syscall/invoke_objdir.c
+++ b/syscall/invoke_objdir.c
@@ -1,34 +1,98 @@
#include "handles.h"
#include "syscall.h"
+#include "error.h"
+#include "lock.h"
+#include "print.h"
static int
-s_handle_invoke_objdir_nmemb(objdir_t *root_dir, objdir_t *target_dir, void *payload)
+s_handle_invoke_objdir_nmemb(
+ objdir_t *root_dir,
+ objdir_t *target_dir,
+ uint8_t *payload,
+ size_t payload_at
+ )
{
- struct syscallInvoke_objdir_nmemb *payloadStruct = payload;
- payloadStruct->value = target_dir->self.data;
- return 0;
+ uint8_t *dest;
+ SYSCALL_PAYLOAD_TAKEP(payload, payload_at, dest, uint8_t);
+
+ *dest = target_dir->self.data;
+
+#ifdef DBG_SYSCALL
+ klogf("objdir_nmemb %p[%i]\n", dest, *dest);
+#endif
+ return KE_OK;
+}
+
+static int
+s_handle_invoke_objdir_getmemb(
+ objdir_t *root_dir,
+ objdir_t *target_dir,
+ uint8_t *payload,
+ size_t payload_at
+ )
+{
+ path_byte_t member;
+ obj_type_t *dest;
+
+ SYSCALL_PAYLOAD_TAKEL(payload, payload_at, member, uint8_t);
+ SYSCALL_PAYLOAD_TAKEP(payload, payload_at, dest, obj_type_t);
+
+ *dest = target_dir->entries[member].type;
+
+#ifdef DBG_SYSCALL
+ klogf("objdir_getmemb %i ret %i\n", member, *dest);
+#endif
+ return KE_OK;
}
static int
-s_handle_invoke_objdir_getmemb(objdir_t *root_dir, objdir_t *target_dir, void *payload)
+s_handle_invoke_objdir_lastfree(
+ objdir_t *root_dir,
+ objdir_t *target_dir,
+ uint8_t *payload,
+ size_t payload_at
+ )
{
- struct syscallInvoke_objdir_getmemb *payloadStruct = payload;
- payloadStruct->value = target_dir->entries[payloadStruct->member].type;
- return 0;
+ path_byte_t *dest;
+ SYSCALL_PAYLOAD_TAKEP(payload, payload_at, dest, path_byte_t);
+
+ for(int i = 0; i < 256; i++) {
+ if(target_dir->entries[i].type == KO_NONE) {
+ *dest = (path_byte_t)i;
+ return KE_OK;
+ }
+ }
+ return -KE_FULL;
}
-static int (*s_invoke_handles[])(objdir_t*, objdir_t*, void*) = {
+static int (*s_invoke_handles[])(objdir_t*, objdir_t*, uint8_t*, size_t) = {
[INVOKE_OBJDIR_NMEMB] = s_handle_invoke_objdir_nmemb,
- [INVOKE_OBJDIR_GETMEMB] = s_handle_invoke_objdir_getmemb
+ [INVOKE_OBJDIR_GETMEMB] = s_handle_invoke_objdir_getmemb,
+ [INVOKE_OBJDIR_LASTFREE] = s_handle_invoke_objdir_lastfree
};
static size_t s_invoke_handles_count = sizeof(s_invoke_handles) / sizeof(void*);
int
-syscall_handle_invoke_objdir(objdir_t *root_dir, objdir_t *target_dir, void *payload)
+syscall_handle_invoke_objdir(
+ objdir_t *root_dir,
+ objdir_entry_t *target_entry,
+ uint8_t *payload,
+ size_t payload_at
+ )
{
- struct syscallInvokeHeader *invokeHeader = payload;
- size_t funcid = invokeHeader->func_id;
+ uint8_t funcid;
+ SYSCALL_PAYLOAD_TAKEL(payload, payload_at, funcid, uint8_t);
+
+ if(funcid >= s_invoke_handles_count) return -KE_BADFUNC;
+ objdir_t *target_dir = (objdir_t*)target_entry->data;
+
+ if((void*)target_entry == root_dir) target_dir = root_dir;
+#ifdef DBG_SYSCALL
+ klogf("Call %i root_dir %p target %p\n", funcid, root_dir, target_entry);
+#endif
- if(funcid >= s_invoke_handles_count) return -1;
- return s_invoke_handles[funcid](root_dir, target_dir, payload);
+ mtx_acquire(&target_entry->lock);
+ int e = s_invoke_handles[funcid](root_dir, target_dir, payload, payload_at);
+ mtx_release(&target_entry->lock);
+ return e;
}