syscall: add lots of syscalls
This commit is contained in:
196
syscall/msg.c
Normal file
196
syscall/msg.c
Normal file
@@ -0,0 +1,196 @@
|
||||
#include <kernel/channel.h>
|
||||
#include <kernel/port.h>
|
||||
#include <kernel/printk.h>
|
||||
#include <kernel/sched.h>
|
||||
#include <kernel/syscall.h>
|
||||
#include <kernel/vm-region.h>
|
||||
|
||||
kern_status_t sys_channel_create(
|
||||
unsigned int id,
|
||||
channel_flags_t flags,
|
||||
kern_handle_t *out)
|
||||
{
|
||||
struct task *self = current_task();
|
||||
if (!validate_access_w(self, out, sizeof *out)) {
|
||||
return KERN_MEMORY_FAULT;
|
||||
}
|
||||
|
||||
struct channel *channel = channel_create();
|
||||
if (!channel) {
|
||||
return KERN_NO_MEMORY;
|
||||
}
|
||||
|
||||
unsigned long irq_flags;
|
||||
task_lock_irqsave(self, &irq_flags);
|
||||
|
||||
if (task_get_channel(self, id)) {
|
||||
task_unlock_irqrestore(self, irq_flags);
|
||||
return KERN_NAME_EXISTS;
|
||||
}
|
||||
|
||||
kern_handle_t handle;
|
||||
kern_status_t status
|
||||
= task_open_handle(self, &channel->c_base, 0, &handle);
|
||||
if (status != KERN_OK) {
|
||||
task_unlock_irqrestore(self, irq_flags);
|
||||
object_unref(&channel->c_base);
|
||||
return status;
|
||||
}
|
||||
|
||||
task_add_channel(self, channel, id);
|
||||
task_unlock_irqrestore(self, irq_flags);
|
||||
|
||||
*out = handle;
|
||||
return KERN_OK;
|
||||
}
|
||||
|
||||
kern_status_t sys_port_create(kern_handle_t *out)
|
||||
{
|
||||
struct task *self = current_task();
|
||||
if (!validate_access_w(self, out, sizeof *out)) {
|
||||
return KERN_MEMORY_FAULT;
|
||||
}
|
||||
|
||||
struct port *port = port_create();
|
||||
if (!port) {
|
||||
return KERN_NO_MEMORY;
|
||||
}
|
||||
|
||||
unsigned long irq_flags;
|
||||
task_lock_irqsave(self, &irq_flags);
|
||||
|
||||
kern_handle_t handle;
|
||||
kern_status_t status
|
||||
= task_open_handle(self, &port->p_base, 0, &handle);
|
||||
if (status != KERN_OK) {
|
||||
task_unlock_irqrestore(self, irq_flags);
|
||||
object_unref(&port->p_base);
|
||||
return status;
|
||||
}
|
||||
|
||||
task_unlock_irqrestore(self, irq_flags);
|
||||
|
||||
*out = handle;
|
||||
return KERN_OK;
|
||||
}
|
||||
|
||||
kern_status_t sys_port_connect(
|
||||
kern_handle_t port_handle,
|
||||
tid_t task_id,
|
||||
unsigned int channel_id)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
struct task *self = current_task();
|
||||
task_lock_irqsave(self, &flags);
|
||||
|
||||
struct object *port_obj = NULL;
|
||||
handle_flags_t port_handle_flags = 0;
|
||||
kern_status_t status = task_resolve_handle(
|
||||
self,
|
||||
port_handle,
|
||||
&port_obj,
|
||||
&port_handle_flags);
|
||||
if (status != KERN_OK) {
|
||||
return status;
|
||||
}
|
||||
|
||||
/* add a reference to the port object to make sure it isn't deleted
|
||||
* while we're using it */
|
||||
object_ref(port_obj);
|
||||
task_unlock_irqrestore(self, flags);
|
||||
|
||||
struct task *remote_task = task_from_tid(task_id);
|
||||
if (!remote_task) {
|
||||
return KERN_NO_ENTRY;
|
||||
}
|
||||
|
||||
task_lock_irqsave(remote_task, &flags);
|
||||
|
||||
struct channel *remote = task_get_channel(remote_task, channel_id);
|
||||
if (!remote) {
|
||||
task_unlock_irqrestore(remote_task, flags);
|
||||
return KERN_NO_ENTRY;
|
||||
}
|
||||
|
||||
object_ref(&remote->c_base);
|
||||
task_unlock_irqrestore(remote_task, flags);
|
||||
|
||||
status = port_connect(port_cast(port_obj), remote);
|
||||
object_unref(port_obj);
|
||||
object_unref(&remote->c_base);
|
||||
|
||||
return KERN_OK;
|
||||
}
|
||||
|
||||
kern_status_t sys_port_disconnect(kern_handle_t port)
|
||||
{
|
||||
return KERN_UNIMPLEMENTED;
|
||||
}
|
||||
|
||||
kern_status_t sys_msg_send(
|
||||
kern_handle_t port,
|
||||
msg_flags_t flags,
|
||||
const struct msg *req,
|
||||
struct msg *resp)
|
||||
{
|
||||
return KERN_UNIMPLEMENTED;
|
||||
}
|
||||
|
||||
kern_status_t sys_msg_recv(
|
||||
kern_handle_t channel,
|
||||
msg_flags_t flags,
|
||||
msgid_t *out_id,
|
||||
struct msg *out_msg)
|
||||
{
|
||||
return KERN_UNIMPLEMENTED;
|
||||
}
|
||||
|
||||
kern_status_t sys_msg_reply(
|
||||
kern_handle_t channel,
|
||||
msg_flags_t flags,
|
||||
msgid_t id,
|
||||
const struct msg *reply)
|
||||
{
|
||||
return KERN_UNIMPLEMENTED;
|
||||
}
|
||||
|
||||
kern_status_t sys_msg_read(
|
||||
kern_handle_t channel,
|
||||
msgid_t id,
|
||||
size_t offset,
|
||||
struct iovec *out,
|
||||
size_t nr_out)
|
||||
{
|
||||
return KERN_UNIMPLEMENTED;
|
||||
}
|
||||
|
||||
kern_status_t sys_msg_read_handles(
|
||||
kern_handle_t channel,
|
||||
msgid_t id,
|
||||
size_t offset,
|
||||
struct handle_list *out,
|
||||
size_t nr_out)
|
||||
{
|
||||
return KERN_UNIMPLEMENTED;
|
||||
}
|
||||
|
||||
kern_status_t sys_msg_write(
|
||||
kern_handle_t channel,
|
||||
msgid_t id,
|
||||
size_t offset,
|
||||
const struct iovec *in,
|
||||
size_t nr_in)
|
||||
{
|
||||
return KERN_UNIMPLEMENTED;
|
||||
}
|
||||
|
||||
kern_status_t sys_msg_write_handles(
|
||||
kern_handle_t channel,
|
||||
msgid_t id,
|
||||
size_t offset,
|
||||
const struct handle_list *in,
|
||||
size_t nr_in)
|
||||
{
|
||||
return KERN_UNIMPLEMENTED;
|
||||
}
|
||||
Reference in New Issue
Block a user