bool vsyscall_exec(const char * name, exception_t ** err, void * ret, va_list args) { // Sanity check if (exception_check(err)) { return false; } const syscall_t * syscall = syscall_get(name); if (syscall == NULL) { exception_set(err, EINVAL, "Syscall %s doesn't exist!", name); return false; } char array[SYSCALL_BUFFERMAX]; { exception_t * e = NULL; ssize_t wrote = vserialize_2array_wheader((void **)array, SYSCALL_BUFFERMAX, &e, method_params(syscall->signature), args); if (wrote <= 0 || exception_check(&e)) { exception_set(err, ENOMEM, "Could not pack '%s' syscall args: %s (SYSCALL_BUFSIZE = %d)", name, exception_message(e), SYSCALL_BUFFERMAX); return false; } } return asyscall_exec(name, err, ret, (void **)array); }
syscall_t * syscall_new(const char * name, const char * sig, syscall_f func, const char * desc, exception_t ** err) { // Sanity check { if (exception_check(err)) { return NULL; } if (name == NULL || sig == NULL) { exception_set(err, EINVAL, "Bad arguments!"); return NULL; } } syscall_t * syscall = kobj_new("Syscall", name, syscall_desc, syscall_destroy, sizeof(syscall_t)); syscall->name = strdup(name); syscall->signature = strdup(sig); syscall->func = func; syscall->description = (desc == NULL)? NULL : strdup(desc); syscall->ffi = function_build(syscall->func, syscall->signature, err); if (syscall->ffi == NULL || exception_check(err)) { return NULL; } hashtable_put(&syscalls, syscall->name, &syscall->global_entry); LOGK(LOG_DEBUG, "Registered syscall %s with sig %s", name, sig); return syscall; }
/* Throw exceptions */ void exception_throw(register int x, register const char *file, register int line, register const char *function) { /* Let's assure we won't throw zero, shall we? */ if(x) { /* First let's backup our data and get a new handler */ exception_handler handler; handler = exception_add_handler(EXCEPTION_THROWN, (bool *)&handler, file, line, function); /* Are we inside any try block? */ if(exception_last_handler()) { /* Check it's state */ if(handler->status == EXCEPTION_RETURN) { /* If we've returned, act as there were no exception at all, deleting it */ exception_pop_handler(); /* Make sure we're error-free */ exception_clear(); } else { /* We have to set the exception itself */ exception_set(x); /* We can go back to check newer handlers, if any */ exception_save_zombies(); /* And we have to return to the previous handler */ exception_return_home(exception_get_handler(EXCEPTION_LIVING)); }; } else { /* Ooops! Called throw outside try! */ (*exception_panic)(EXCEPTION_UNCAUGHT); }; }; };
/* Cleans the current error flag */ void exception_clear(void) { /* Here we have to set the exception to zero (NULL) */ exception_set(0); /* And remove everything if we just rescued an error */ exception_handler handler = exception_find_handler(EXCEPTION_RESCUE); if(handler) { while(handler != exception_last_handler()) { exception_pop_handler(); }; }; };
bool asyscall_exec(const char * name, exception_t ** err, void * ret, void ** args) { // Sanity check if (exception_check(err)) { return false; } syscall_t * syscall = syscall_get(name); if (syscall == NULL) { exception_set(err, EINVAL, "Syscall %s doesn't exist!", name); return false; } function_call(syscall->ffi, ret, args); return true; }