113 lines
2.3 KiB
C
113 lines
2.3 KiB
C
#include <mango/msg.h>
|
|
#include <string.h>
|
|
#include <xpc/msg.h>
|
|
|
|
void xpc_msg_header_init(
|
|
xpc_msg_header_t *msg,
|
|
unsigned long interface,
|
|
unsigned short func)
|
|
{
|
|
memset(msg, 0x0, sizeof *msg);
|
|
|
|
msg->hdr_magic = XPC_MSG_MAGIC;
|
|
msg->hdr_interface = interface;
|
|
msg->hdr_func = func;
|
|
msg->hdr_status = 0;
|
|
}
|
|
|
|
bool xpc_msg_header_validate(const xpc_msg_header_t *msg)
|
|
{
|
|
return msg->hdr_magic == XPC_MSG_MAGIC;
|
|
}
|
|
|
|
kern_status_t xpc_msg_recv(kern_handle_t channel, xpc_msg_t *out)
|
|
{
|
|
kern_iovec_t iov = IOVEC(&out->msg_header, sizeof out->msg_header);
|
|
kern_msg_t msg = {
|
|
.msg_data = &iov,
|
|
.msg_data_count = 1,
|
|
.msg_handles = out->msg_handles,
|
|
.msg_handles_count = KERN_MSG_MAX_HANDLES,
|
|
};
|
|
kern_status_t status = msg_recv(channel, &msg);
|
|
if (status != KERN_OK) {
|
|
return status;
|
|
}
|
|
|
|
if (!xpc_msg_header_validate(&out->msg_header)) {
|
|
return KERN_INVALID_ARGUMENT;
|
|
}
|
|
|
|
out->msg_sender.e_channel = channel;
|
|
out->msg_sender.e_task = msg.msg_sender;
|
|
out->msg_sender.e_port = msg.msg_endpoint;
|
|
out->msg_sender.e_msg = msg.msg_id;
|
|
|
|
return KERN_OK;
|
|
}
|
|
|
|
kern_status_t xpc_msg_read(
|
|
const xpc_msg_t *msg,
|
|
size_t offset,
|
|
void *p,
|
|
size_t count)
|
|
{
|
|
kern_iovec_t iov = IOVEC(p, count);
|
|
size_t r = 0;
|
|
return msg_read(
|
|
msg->msg_sender.e_channel,
|
|
msg->msg_sender.e_msg,
|
|
offset,
|
|
&iov,
|
|
1,
|
|
&r);
|
|
}
|
|
|
|
kern_status_t xpc_msg_write(
|
|
const xpc_msg_t *msg,
|
|
size_t offset,
|
|
const void *p,
|
|
size_t count)
|
|
{
|
|
kern_iovec_t iov = IOVEC(p, count);
|
|
size_t w = 0;
|
|
return msg_write(
|
|
msg->msg_sender.e_channel,
|
|
msg->msg_sender.e_msg,
|
|
offset,
|
|
&iov,
|
|
1,
|
|
&w);
|
|
}
|
|
|
|
kern_status_t xpc_msg_reply(
|
|
const xpc_msg_t *msg,
|
|
kern_iovec_t *iov,
|
|
size_t iov_count,
|
|
kern_msg_handle_t *handles,
|
|
size_t handle_count)
|
|
{
|
|
kern_msg_t reply = MSG(iov, iov_count, handles, handle_count);
|
|
return msg_reply(
|
|
msg->msg_sender.e_channel,
|
|
msg->msg_sender.e_msg,
|
|
&reply);
|
|
}
|
|
|
|
kern_status_t xpc_msg_reply_error(const xpc_msg_t *msg, unsigned short code)
|
|
{
|
|
xpc_msg_header_t reply_data = {
|
|
.hdr_magic = XPC_MSG_MAGIC,
|
|
.hdr_interface = msg->msg_header.hdr_interface,
|
|
.hdr_func = msg->msg_header.hdr_func,
|
|
.hdr_status = code,
|
|
};
|
|
|
|
kern_iovec_t iov = IOVEC(&reply_data, sizeof reply_data);
|
|
kern_msg_t reply = MSG(&iov, 1, NULL, 0);
|
|
return msg_reply(
|
|
msg->msg_sender.e_channel,
|
|
msg->msg_sender.e_msg,
|
|
&reply);
|
|
}
|