kernel: add a syscall to duplicate a handle
This commit is contained in:
@@ -121,6 +121,9 @@ extern kern_status_t sys_address_space_release(
|
||||
|
||||
extern kern_status_t sys_kern_log(const char *s);
|
||||
extern kern_status_t sys_kern_handle_close(kern_handle_t handle);
|
||||
extern kern_status_t sys_kern_handle_duplicate(
|
||||
kern_handle_t handle,
|
||||
kern_handle_t *out);
|
||||
extern kern_status_t sys_kern_config_get(
|
||||
kern_config_key_t key,
|
||||
void *ptr,
|
||||
|
||||
@@ -77,6 +77,7 @@ SYSCALL_GATE address_space_release SYS_ADDRESS_SPACE_RELEASE 3
|
||||
|
||||
SYSCALL_GATE kern_log SYS_KERN_LOG 1
|
||||
SYSCALL_GATE kern_handle_close SYS_KERN_HANDLE_CLOSE 1
|
||||
SYSCALL_GATE kern_handle_duplicate SYS_KERN_HANDLE_DUPLICATE 2
|
||||
SYSCALL_GATE kern_config_get SYS_KERN_CONFIG_GET 3
|
||||
SYSCALL_GATE kern_config_set SYS_KERN_CONFIG_SET 3
|
||||
|
||||
|
||||
@@ -5,5 +5,8 @@
|
||||
#include <mango/types.h>
|
||||
|
||||
extern kern_status_t kern_handle_close(kern_handle_t handle);
|
||||
extern kern_status_t kern_handle_duplicate(
|
||||
kern_handle_t handle,
|
||||
kern_handle_t *out);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -23,6 +23,7 @@ static const virt_addr_t syscall_table[] = {
|
||||
SYSCALL_TABLE_ENTRY(ADDRESS_SPACE_RELEASE, address_space_release),
|
||||
SYSCALL_TABLE_ENTRY(KERN_LOG, kern_log),
|
||||
SYSCALL_TABLE_ENTRY(KERN_HANDLE_CLOSE, kern_handle_close),
|
||||
SYSCALL_TABLE_ENTRY(KERN_HANDLE_DUPLICATE, kern_handle_duplicate),
|
||||
SYSCALL_TABLE_ENTRY(KERN_CONFIG_GET, kern_config_get),
|
||||
SYSCALL_TABLE_ENTRY(KERN_CONFIG_SET, kern_config_set),
|
||||
SYSCALL_TABLE_ENTRY(CHANNEL_CREATE, channel_create),
|
||||
|
||||
@@ -4,5 +4,36 @@
|
||||
kern_status_t sys_kern_handle_close(kern_handle_t handle)
|
||||
{
|
||||
struct task *self = current_task();
|
||||
|
||||
return task_close_handle(self, handle);
|
||||
}
|
||||
|
||||
kern_status_t sys_kern_handle_duplicate(
|
||||
kern_handle_t handle,
|
||||
kern_handle_t *out)
|
||||
{
|
||||
struct task *self = current_task();
|
||||
|
||||
if (!validate_access_w(self, out, sizeof *out)) {
|
||||
return KERN_MEMORY_FAULT;
|
||||
}
|
||||
|
||||
unsigned long flags;
|
||||
task_lock_irqsave(self, &flags);
|
||||
|
||||
struct object *obj = NULL;
|
||||
handle_flags_t handle_flags = 0;
|
||||
kern_status_t status
|
||||
= task_resolve_handle(self, handle, &obj, &handle_flags);
|
||||
if (status != KERN_OK) {
|
||||
task_unlock_irqrestore(self, flags);
|
||||
return status;
|
||||
}
|
||||
|
||||
status = task_open_handle(self, obj, handle_flags, out);
|
||||
object_unref(obj);
|
||||
|
||||
task_unlock_irqrestore(self, flags);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user