struct cpu_state* syscall(struct cpu_state* cpu) { save_cpu_state(cpu); cpu = get_current_task()->cpuState; switch (cpu->eax) { case 1: /* exit */ return terminate_current(cpu); case 3: /* exec */ { cpu->eax = vfs_exec((char*) cpu->ebx, (char**) cpu->ecx); } break; case 4: /* getargs */ { cpu->eax = (uint32_t) get_current_task()->args; } break; case 5: /* yield */ { cpu = schedule(cpu); } break; case 10: /* fopen */ { char* name = strclone((char*) cpu->ebx); uint32_t fmode = (uint32_t) cpu->ecx; struct res_handle* handle = vfs_open(name, fmode); if(handle) { register_handle(handle); cpu->eax = (uint32_t) handle; } else { cpu->eax = 0; } free(name); } break; case 11: /* fclose */ { struct res_handle* handle = (void*) cpu->ebx; if(!unregister_handle(handle)) { vfs_close(handle); cpu->eax = 0; } else { cpu->eax = (uint32_t) -1; } } break; case 12: /* fwrite */ { struct res_handle* handle = (void*) cpu->ebx; if(handle != 0) { cpu->eax = vfs_write(handle, (char*) cpu->ecx, cpu->edx, 1); } else { cpu->eax = RW_ERR_VFS; } } break; case 13: /* fread */ { struct res_handle* handle = (void*) cpu->ebx; if(handle != 0) { cpu->eax = vfs_read(handle, (char*) cpu->ecx, cpu->edx, 1); } else { cpu->eax = RW_ERR_VFS; } } break; case 14: /* fmkfifo */ { char* name = strclone((char*) cpu->ebx); vfs_create_kfile(name, ramfs_fifo_driver_struct(), &(uint32_t){4096}); //default to 4k Buffer-size struct res_handle* handle = vfs_open(name, FM_READ | FM_WRITE); if(handle) { register_handle(handle); cpu->eax = (uint32_t) handle; } else { cpu->eax = 0; } free(name); } break; case 20: /* getpmhandle */ { struct res_handle* handle = 0; switch(cpu->ebx) { case PMID_STDOUT: handle = get_current_task()->stdout; break; case PMID_STDIN: handle = get_current_task()->stdin; break; case PMID_STDERR: handle = get_current_task()->stderr; break; default: handle = get_current_task()->stdout; break; } cpu->eax = (uint32_t) handle; } break; case 21: /* fopenpmhandle */ { char* path = strclone((char*)cpu->ecx); struct res_handle* open; uint32_t fm = FM_WRITE; if(cpu->ebx == PMID_STDIN) { fm = FM_READ; } open = vfs_open(path, fm); free(path); if(!open) { cpu->eax = (uint32_t) -1; break; } struct res_handle* oldhandle = 0; switch(cpu->ebx) { case PMID_STDOUT: oldhandle = get_current_task()->stdout; get_current_task()->stdout = open; break; case PMID_STDIN: oldhandle = get_current_task()->stdin; get_current_task()->stdin = open; break; case PMID_STDERR: oldhandle = get_current_task()->stderr; get_current_task()->stderr = open; break; default: oldhandle = get_current_task()->stdout; get_current_task()->stdout = open; break; } if(oldhandle != 0) { vfs_close(oldhandle); } cpu->eax = 0; } break; case 201: /* kputc */ cpu->eax = kprintf("%c", cpu->ebx); break; case 202: /* kputs */ cpu->eax = kprintf("%s", cpu->ebx); break; case 203: /* vmm_alloc_ucont */ cpu->eax = (uint32_t) vmm_alloc_ucont(cpu->ebx); break; case 204: /* vmm_free */ cpu->eax = 0; if (cpu->ebx >= PROGRAM_BOTTOM) { //Only in PROGRAM AREA ;) vmm_free((void*) cpu->ebx); } break; case 205: /* pmm_print_stats */ pmm_print_stats(); break; default: kprintf("Invalid Syscall %d...", cpu->eax); break; } return cpu; }
static gboolean handle_close (XdpRequest *object, GDBusMethodInvocation *invocation, Request *request) { g_autoptr(GError) error = NULL; REQUEST_AUTOLOCK (request); if (request->exported) { const char *handle = g_object_get_data (G_OBJECT (request), "impl-handle"); if (!xdp_impl_file_chooser_call_close_sync (impl, request->sender, request->app_id, handle, NULL, &error)) { g_dbus_method_invocation_return_gerror (invocation, error); return TRUE; } unregister_handle (handle); request_unexport (request); } xdp_request_complete_close (XDP_REQUEST (request), invocation); return TRUE; }
static void emit_response (XdpImplFileChooser *object, gboolean for_save, const gchar *arg_destination, const gchar *arg_handle, guint arg_response, const gchar *const *arg_uris, GVariant *arg_options) { g_autoptr(Request) request = lookup_request_by_handle (arg_handle); GVariantBuilder uris; GVariantBuilder results; g_autofree char *ruri = NULL; gboolean writable = TRUE; g_autoptr(GError) error = NULL; g_autoptr(GVariant) choices = NULL; int i; if (request == NULL) return; REQUEST_AUTOLOCK (request); if (!g_variant_lookup (arg_options, "b", "writable", &writable)) writable = FALSE; g_variant_builder_init (&results, G_VARIANT_TYPE_VARDICT); choices = g_variant_lookup_value (arg_options, "choices", G_VARIANT_TYPE ("a(ss)")); if (choices) g_variant_builder_add (&results, "{sv}", "choices", choices); g_variant_builder_init (&uris, G_VARIANT_TYPE ("as")); for (i = 0; arg_uris[i] != NULL; i++) { const char *uri = arg_uris[i]; ruri = register_document (uri, request->app_id, for_save, writable, &error); if (ruri == NULL) { g_warning ("Failed to register %s: %s\n", uri, error->message); g_clear_error (&error); } else { g_debug ("convert uri %s -> %s\n", uri, ruri); g_variant_builder_add (&uris, "s", ruri); } } g_variant_builder_add (&results, "{&sv}", "uris", g_variant_builder_end (&uris)); if (request->exported) { xdp_request_emit_response (XDP_REQUEST (request), arg_response, g_variant_builder_end (&results)); unregister_handle (arg_handle); request_unexport (request); } }