lib: xpc: implement scatter/gather i/o for buffers and messages

This commit is contained in:
2026-03-24 12:40:16 +00:00
parent af3dd454b0
commit 1eb6853cb0
5 changed files with 162 additions and 18 deletions

View File

@@ -5,6 +5,7 @@
kern_status_t xpc_buffer_read( kern_status_t xpc_buffer_read(
const xpc_buffer_t *buf, const xpc_buffer_t *buf,
size_t offset,
void *out, void *out,
size_t max, size_t max,
size_t *nr_read) size_t *nr_read)
@@ -14,25 +15,35 @@ kern_status_t xpc_buffer_read(
return KERN_BAD_STATE; return KERN_BAD_STATE;
} }
size_t to_read = max; if (offset >= buf->buf_len) {
if (to_read > buf->buf_len) { if (nr_read) {
to_read = buf->buf_len; *nr_read = 0;
} }
kern_status_t status return KERN_OK;
= xpc_msg_read(buf->buf_origin, buf->buf_offset, out, to_read); }
size_t to_read = max;
if (offset + to_read > buf->buf_len) {
to_read = buf->buf_len - offset;
}
kern_status_t status = xpc_msg_read(
buf->buf_origin,
buf->buf_offset + offset,
out,
to_read,
nr_read);
if (status != KERN_OK) { if (status != KERN_OK) {
return status; return status;
} }
/* TODO */
*nr_read = to_read;
return KERN_OK; return KERN_OK;
} }
kern_status_t xpc_buffer_write( kern_status_t xpc_buffer_write(
xpc_buffer_t *buf, xpc_buffer_t *buf,
size_t offset,
const void *in, const void *in,
size_t len, size_t len,
size_t *nr_written) size_t *nr_written)
@@ -41,9 +52,17 @@ kern_status_t xpc_buffer_write(
return KERN_BAD_STATE; return KERN_BAD_STATE;
} }
if (offset >= buf->buf_max) {
if (nr_written) {
*nr_written = 0;
}
return KERN_OK;
}
size_t to_write = len; size_t to_write = len;
if (to_write > buf->buf_max) { if (offset + to_write > buf->buf_max) {
to_write = buf->buf_max; to_write = buf->buf_max - offset;
} }
if (!(buf->buf_flags & XPC_BUFFER_F_REMOTE)) { if (!(buf->buf_flags & XPC_BUFFER_F_REMOTE)) {
@@ -54,8 +73,70 @@ kern_status_t xpc_buffer_write(
return xpc_msg_write( return xpc_msg_write(
buf->buf_origin, buf->buf_origin,
buf->buf_offset, buf->buf_offset + offset,
in, in,
to_write, to_write,
nr_written); nr_written);
} }
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;
}

View File

@@ -1,6 +1,7 @@
#ifndef XPC_BUFFER_H_ #ifndef XPC_BUFFER_H_
#define XPC_BUFFER_H_ #define XPC_BUFFER_H_
#include <mango/types.h>
#include <stddef.h> #include <stddef.h>
#include <xpc/status.h> #include <xpc/status.h>
@@ -71,13 +72,31 @@ typedef struct xpc_buffer {
extern xpc_status_t xpc_buffer_read( extern xpc_status_t xpc_buffer_read(
const xpc_buffer_t *s, const xpc_buffer_t *s,
size_t offset,
void *out, void *out,
size_t max, size_t max,
size_t *nr_read); size_t *nr_read);
extern xpc_status_t xpc_buffer_write( extern xpc_status_t xpc_buffer_write(
xpc_buffer_t *s, xpc_buffer_t *s,
size_t offset,
const void *in, const void *in,
size_t len, size_t len,
size_t *nr_written); size_t *nr_written);
extern xpc_status_t xpc_buffer_readv(
const xpc_buffer_t *s,
size_t offset,
kern_iovec_t *iov,
size_t nr_iov,
size_t *nr_read);
extern xpc_status_t xpc_buffer_writev(
xpc_buffer_t *s,
size_t offset,
kern_iovec_t *iov,
size_t nr_iov,
size_t *nr_written);
extern xpc_status_t xpc_buffer_length(const xpc_buffer_t *s);
extern xpc_status_t xpc_buffer_capacity(const xpc_buffer_t *s);
#endif #endif

View File

@@ -34,7 +34,8 @@ extern kern_status_t xpc_msg_read(
const xpc_msg_t *msg, const xpc_msg_t *msg,
size_t offset, size_t offset,
void *p, void *p,
size_t count); size_t count,
size_t *nr_read);
extern kern_status_t xpc_msg_write( extern kern_status_t xpc_msg_write(
const xpc_msg_t *msg, const xpc_msg_t *msg,
size_t offset, size_t offset,
@@ -42,6 +43,19 @@ extern kern_status_t xpc_msg_write(
size_t count, size_t count,
size_t *nr_written); size_t *nr_written);
extern kern_status_t xpc_msg_readv(
const xpc_msg_t *msg,
size_t offset,
kern_iovec_t *iov,
size_t nr_iov,
size_t *nr_read);
extern kern_status_t xpc_msg_writev(
const xpc_msg_t *msg,
size_t offset,
kern_iovec_t *iov,
size_t nr_iov,
size_t *nr_written);
extern kern_status_t xpc_msg_reply( extern kern_status_t xpc_msg_reply(
const xpc_msg_t *msg, const xpc_msg_t *msg,
kern_iovec_t *iov, kern_iovec_t *iov,

View File

@@ -89,17 +89,17 @@ kern_status_t xpc_msg_read(
const xpc_msg_t *msg, const xpc_msg_t *msg,
size_t offset, size_t offset,
void *p, void *p,
size_t count) size_t count,
size_t *nr_read)
{ {
kern_iovec_t iov = IOVEC(p, count); kern_iovec_t iov = IOVEC(p, count);
size_t r = 0;
return msg_read( return msg_read(
msg->msg_sender.e_channel, msg->msg_sender.e_channel,
msg->msg_sender.e_msg, msg->msg_sender.e_msg,
offset, offset,
&iov, &iov,
1, 1,
&r); nr_read);
} }
kern_status_t xpc_msg_write( kern_status_t xpc_msg_write(
@@ -119,6 +119,38 @@ kern_status_t xpc_msg_write(
nr_written); nr_written);
} }
kern_status_t xpc_msg_readv(
const xpc_msg_t *msg,
size_t offset,
kern_iovec_t *iov,
size_t nr_iov,
size_t *nr_read)
{
return msg_read(
msg->msg_sender.e_channel,
msg->msg_sender.e_msg,
offset,
iov,
nr_iov,
nr_read);
}
kern_status_t xpc_msg_writev(
const xpc_msg_t *msg,
size_t offset,
kern_iovec_t *iov,
size_t nr_iov,
size_t *nr_written)
{
return msg_write(
msg->msg_sender.e_channel,
msg->msg_sender.e_msg,
offset,
iov,
nr_iov,
nr_written);
}
kern_status_t xpc_msg_reply( kern_status_t xpc_msg_reply(
const xpc_msg_t *msg, const xpc_msg_t *msg,
kern_iovec_t *iov, kern_iovec_t *iov,

View File

@@ -19,14 +19,12 @@ xpc_status_t xpc_string_read(
} }
kern_status_t status kern_status_t status
= xpc_msg_read(s->s_origin, s->s_offset, out, to_read); = xpc_msg_read(s->s_origin, s->s_offset, out, to_read, nr_read);
if (status != KERN_OK) { if (status != KERN_OK) {
return status; return status;
} }
out[to_read] = '\0'; out[to_read] = '\0';
/* TODO */
*nr_read = to_read;
return KERN_OK; return KERN_OK;
} }