mirror of
https://github.com/justinian/jsix.git
synced 2025-12-09 16:04:32 -08:00
Instead of handles / capabilities having numeric ids that are only valid for the owning process, they are now global in a system capabilities table. This will allow for specifying capabilities in IPC that doesn't need to be kernel-controlled. Processes will still need to be granted access to given capabilities, but that can become a simpler system call than the current method of sending them through mailbox messages (and worse, having to translate every one into a new capability like was the case before). In order to track which handles a process has access to, a new node_set based on node_map allows for an efficient storage and lookup of handles.
213 lines
4.3 KiB
C++
213 lines
4.3 KiB
C++
#include <j6/errors.h>
|
|
#include <j6/flags.h>
|
|
#include <util/util.h>
|
|
|
|
#include "objects/mailbox.h"
|
|
#include "objects/thread.h"
|
|
#include "syscalls/helpers.h"
|
|
|
|
using namespace obj;
|
|
|
|
namespace syscalls {
|
|
|
|
j6_status_t
|
|
mailbox_create(j6_handle_t *self)
|
|
{
|
|
construct_handle<mailbox>(self);
|
|
return j6_status_ok;
|
|
}
|
|
|
|
j6_status_t
|
|
mailbox_close(mailbox *self)
|
|
{
|
|
if (self->closed())
|
|
return j6_status_closed;
|
|
|
|
self->close();
|
|
return j6_status_ok;
|
|
}
|
|
|
|
j6_status_t
|
|
prep_send(
|
|
mailbox::message *msg,
|
|
uint64_t tag,
|
|
uint64_t subtag,
|
|
const j6_handle_t *handles,
|
|
size_t handle_count)
|
|
{
|
|
if (!msg ||
|
|
handle_count > mailbox::max_handle_count)
|
|
return j6_err_invalid_arg;
|
|
|
|
msg->tag = tag;
|
|
msg->subtag = subtag;
|
|
|
|
msg->handle_count = handle_count;
|
|
memcpy(msg->handles, handles, sizeof(j6_handle_t) * handle_count);
|
|
|
|
return j6_status_ok;
|
|
}
|
|
|
|
void
|
|
prep_receive(
|
|
mailbox::message *msg,
|
|
uint64_t *tag,
|
|
uint64_t *subtag,
|
|
uint16_t *reply_tag,
|
|
j6_handle_t *handles,
|
|
size_t *handle_count)
|
|
{
|
|
if (tag) *tag = msg->tag;
|
|
if (subtag) *subtag = msg->subtag;
|
|
if (reply_tag) *reply_tag = msg->reply_tag;
|
|
|
|
*handle_count = msg->handle_count;
|
|
process &proc = process::current();
|
|
for (size_t i = 0; i < msg->handle_count; ++i) {
|
|
proc.add_handle(msg->handles[i]);
|
|
handles[i] = msg->handles[i];
|
|
}
|
|
}
|
|
|
|
j6_status_t
|
|
mailbox_send(
|
|
mailbox *self,
|
|
uint64_t tag,
|
|
uint64_t subtag,
|
|
j6_handle_t * handles,
|
|
size_t handle_count)
|
|
{
|
|
mailbox::message *msg = new mailbox::message;
|
|
|
|
j6_status_t s = prep_send(msg,
|
|
tag, subtag,
|
|
handles, handle_count);
|
|
|
|
if (s != j6_status_ok) {
|
|
delete msg;
|
|
return s;
|
|
}
|
|
|
|
self->send(msg);
|
|
return j6_status_ok;
|
|
}
|
|
|
|
|
|
j6_status_t
|
|
mailbox_receive(
|
|
mailbox *self,
|
|
uint64_t *tag,
|
|
uint64_t *subtag,
|
|
j6_handle_t *handles,
|
|
size_t *handle_count,
|
|
uint16_t *reply_tag,
|
|
uint64_t flags)
|
|
{
|
|
if (*handle_count < mailbox::max_handle_count)
|
|
return j6_err_insufficient;
|
|
|
|
mailbox::message *msg = nullptr;
|
|
|
|
bool block = flags & j6_mailbox_block;
|
|
if (!self->receive(msg, block)) {
|
|
// No message received
|
|
return self->closed() ? j6_status_closed :
|
|
!block ? j6_status_would_block :
|
|
j6_err_unexpected;
|
|
}
|
|
|
|
prep_receive(msg,
|
|
tag, subtag, reply_tag,
|
|
handles, handle_count);
|
|
|
|
if (*reply_tag == 0)
|
|
delete msg;
|
|
return j6_status_ok;
|
|
}
|
|
|
|
|
|
j6_status_t
|
|
mailbox_call(
|
|
mailbox *self,
|
|
uint64_t *tag,
|
|
uint64_t *subtag,
|
|
j6_handle_t *handles,
|
|
size_t *handle_count)
|
|
{
|
|
mailbox::message *msg = new mailbox::message;
|
|
|
|
j6_status_t s = prep_send(msg,
|
|
*tag, *subtag,
|
|
handles, *handle_count);
|
|
|
|
if (s != j6_status_ok) {
|
|
delete msg;
|
|
return s;
|
|
}
|
|
|
|
if (!self->call(msg)) {
|
|
delete msg;
|
|
return self->closed() ? j6_status_closed :
|
|
j6_err_unexpected;
|
|
}
|
|
|
|
prep_receive(msg,
|
|
tag, subtag, 0,
|
|
handles, handle_count);
|
|
|
|
delete msg;
|
|
return j6_status_ok;
|
|
}
|
|
|
|
|
|
j6_status_t
|
|
mailbox_respond(
|
|
mailbox *self,
|
|
uint64_t tag,
|
|
uint64_t subtag,
|
|
j6_handle_t * handles,
|
|
size_t handle_count,
|
|
uint16_t reply_tag)
|
|
{
|
|
mailbox::replyer reply = self->reply(reply_tag);
|
|
if (!reply.valid())
|
|
return j6_err_invalid_arg;
|
|
|
|
j6_status_t s = prep_send(reply.msg, tag, subtag,
|
|
handles, handle_count);
|
|
|
|
if (s != j6_status_ok) {
|
|
reply.error(s);
|
|
return s;
|
|
}
|
|
|
|
return j6_status_ok;
|
|
}
|
|
|
|
|
|
j6_status_t
|
|
mailbox_respond_receive(
|
|
mailbox *self,
|
|
uint64_t *tag,
|
|
uint64_t *subtag,
|
|
j6_handle_t *handles,
|
|
size_t *handle_count,
|
|
size_t handles_in,
|
|
uint16_t *reply_tag,
|
|
uint64_t flags)
|
|
{
|
|
j6_status_t s = mailbox_respond(self, *tag, *subtag, handles, handles_in, *reply_tag);
|
|
if (s != j6_status_ok)
|
|
return s;
|
|
|
|
s = mailbox_receive(self, tag, subtag, handles, handle_count, reply_tag, flags);
|
|
if (s != j6_status_ok)
|
|
return s;
|
|
|
|
return j6_status_ok;
|
|
}
|
|
|
|
|
|
|
|
} // namespace syscalls
|