#include #include #include #include #include #include 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; }