Files
rosetta/lib/libxpc/msg.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);
}