Files
jsix/src/kernel/syscalls/mailbox.cpp
Justin C. Miller 4bceac3d56 [kernel] Check for null handle arg in mailbox_call
The handle argument to `mailbox_call` is optional, so needs to be
manually checked by the syscall handler before dereferencing.
2023-07-10 01:34:19 -07:00

93 lines
1.7 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
mailbox_call(
mailbox *self,
uint64_t *tag,
uint64_t *subtag,
j6_handle_t *handle)
{
thread::message_data &data =
thread::current().get_message_data();
data.tag = *tag;
data.subtag = *subtag;
if (handle)
data.handle = *handle;
j6_status_t s = self->call();
if (s != j6_status_ok)
return s;
*tag = data.tag;
*subtag = data.subtag;
if (handle) {
*handle = data.handle;
process::current().add_handle(*handle);
}
return j6_status_ok;
}
j6_status_t
mailbox_respond(
mailbox *self,
uint64_t *tag,
uint64_t *subtag,
j6_handle_t *handle,
uint64_t *reply_tag,
uint64_t flags)
{
thread::message_data data { *tag, *subtag, *handle };
if (*reply_tag) {
j6_status_t s = self->reply(*reply_tag, data);
if (s != j6_status_ok)
return s;
}
bool block = flags & j6_flag_block;
j6_status_t s = self->receive(data, *reply_tag, block);
if (s != j6_status_ok)
return s;
*tag = data.tag;
*subtag = data.subtag;
*handle = data.handle;
process::current().add_handle(*handle);
return j6_status_ok;
}
} // namespace syscalls