2026-03-10 19:14:37 +00:00
|
|
|
#include <mango/status.h>
|
2026-03-15 09:43:00 +00:00
|
|
|
#include <string.h>
|
2026-03-10 19:14:37 +00:00
|
|
|
#include <xpc/buffer.h>
|
|
|
|
|
#include <xpc/msg.h>
|
|
|
|
|
|
|
|
|
|
kern_status_t xpc_buffer_read(
|
|
|
|
|
const xpc_buffer_t *buf,
|
2026-03-24 12:40:16 +00:00
|
|
|
size_t offset,
|
2026-03-10 19:14:37 +00:00
|
|
|
void *out,
|
|
|
|
|
size_t max,
|
|
|
|
|
size_t *nr_read)
|
|
|
|
|
{
|
|
|
|
|
if ((buf->buf_flags & (XPC_BUFFER_F_IN | XPC_BUFFER_F_REMOTE))
|
|
|
|
|
!= (XPC_BUFFER_F_IN | XPC_BUFFER_F_REMOTE)) {
|
|
|
|
|
return KERN_BAD_STATE;
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-24 12:40:16 +00:00
|
|
|
if (offset >= buf->buf_len) {
|
|
|
|
|
if (nr_read) {
|
|
|
|
|
*nr_read = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return KERN_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-10 19:14:37 +00:00
|
|
|
size_t to_read = max;
|
2026-03-24 12:40:16 +00:00
|
|
|
if (offset + to_read > buf->buf_len) {
|
|
|
|
|
to_read = buf->buf_len - offset;
|
2026-03-10 19:14:37 +00:00
|
|
|
}
|
|
|
|
|
|
2026-03-24 12:40:16 +00:00
|
|
|
kern_status_t status = xpc_msg_read(
|
|
|
|
|
buf->buf_origin,
|
|
|
|
|
buf->buf_offset + offset,
|
|
|
|
|
out,
|
|
|
|
|
to_read,
|
|
|
|
|
nr_read);
|
2026-03-10 19:14:37 +00:00
|
|
|
if (status != KERN_OK) {
|
|
|
|
|
return status;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return KERN_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
kern_status_t xpc_buffer_write(
|
|
|
|
|
xpc_buffer_t *buf,
|
2026-03-24 12:40:16 +00:00
|
|
|
size_t offset,
|
2026-03-10 19:14:37 +00:00
|
|
|
const void *in,
|
|
|
|
|
size_t len,
|
|
|
|
|
size_t *nr_written)
|
|
|
|
|
{
|
2026-03-15 09:43:00 +00:00
|
|
|
if (!(buf->buf_flags & XPC_BUFFER_F_OUT)) {
|
2026-03-10 19:14:37 +00:00
|
|
|
return KERN_BAD_STATE;
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-24 12:40:16 +00:00
|
|
|
if (offset >= buf->buf_max) {
|
|
|
|
|
if (nr_written) {
|
|
|
|
|
*nr_written = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return KERN_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-10 19:14:37 +00:00
|
|
|
size_t to_write = len;
|
2026-03-24 12:40:16 +00:00
|
|
|
if (offset + to_write > buf->buf_max) {
|
|
|
|
|
to_write = buf->buf_max - offset;
|
2026-03-10 19:14:37 +00:00
|
|
|
}
|
|
|
|
|
|
2026-03-15 09:43:00 +00:00
|
|
|
if (!(buf->buf_flags & XPC_BUFFER_F_REMOTE)) {
|
|
|
|
|
memcpy(buf->buf_ptr, in, to_write);
|
|
|
|
|
*nr_written = to_write;
|
|
|
|
|
return KERN_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-21 10:52:16 +00:00
|
|
|
return xpc_msg_write(
|
|
|
|
|
buf->buf_origin,
|
2026-03-24 12:40:16 +00:00
|
|
|
buf->buf_offset + offset,
|
2026-03-21 10:52:16 +00:00
|
|
|
in,
|
|
|
|
|
to_write,
|
|
|
|
|
nr_written);
|
2026-03-10 19:14:37 +00:00
|
|
|
}
|
2026-03-24 12:40:16 +00:00
|
|
|
|
|
|
|
|
xpc_status_t xpc_buffer_readv(
|
|
|
|
|
const xpc_buffer_t *buf,
|
|
|
|
|
size_t offset,
|
|
|
|
|
kern_iovec_t *iov,
|
|
|
|
|
size_t nr_iov,
|
|
|
|
|
size_t *nr_read)
|
|
|
|
|
{
|
|
|
|
|
if (!(buf->buf_flags & XPC_BUFFER_F_IN)) {
|
|
|
|
|
return KERN_BAD_STATE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* TODO limit to buffer bounds */
|
|
|
|
|
|
|
|
|
|
if (!(buf->buf_flags & XPC_BUFFER_F_REMOTE)) {
|
|
|
|
|
/* TODO */
|
|
|
|
|
return KERN_UNIMPLEMENTED;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return xpc_msg_readv(
|
|
|
|
|
buf->buf_origin,
|
|
|
|
|
buf->buf_offset + offset,
|
|
|
|
|
iov,
|
|
|
|
|
nr_iov,
|
|
|
|
|
nr_read);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
xpc_status_t xpc_buffer_writev(
|
|
|
|
|
xpc_buffer_t *buf,
|
|
|
|
|
size_t offset,
|
|
|
|
|
kern_iovec_t *iov,
|
|
|
|
|
size_t nr_iov,
|
|
|
|
|
size_t *nr_written)
|
|
|
|
|
{
|
|
|
|
|
if (!(buf->buf_flags & XPC_BUFFER_F_OUT)) {
|
|
|
|
|
return KERN_BAD_STATE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* TODO limit to buffer bounds */
|
|
|
|
|
|
|
|
|
|
if (!(buf->buf_flags & XPC_BUFFER_F_REMOTE)) {
|
|
|
|
|
/* TODO */
|
|
|
|
|
return KERN_UNIMPLEMENTED;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return xpc_msg_writev(
|
|
|
|
|
buf->buf_origin,
|
|
|
|
|
buf->buf_offset + offset,
|
|
|
|
|
iov,
|
|
|
|
|
nr_iov,
|
|
|
|
|
nr_written);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
xpc_status_t xpc_buffer_length(const xpc_buffer_t *s)
|
|
|
|
|
{
|
|
|
|
|
return s->buf_len;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
xpc_status_t xpc_buffer_capacity(const xpc_buffer_t *s)
|
|
|
|
|
{
|
|
|
|
|
return s->buf_max;
|
|
|
|
|
}
|