lib: xpc: implement scatter/gather i/o for buffers and messages
This commit is contained in:
@@ -5,6 +5,7 @@
|
||||
|
||||
kern_status_t xpc_buffer_read(
|
||||
const xpc_buffer_t *buf,
|
||||
size_t offset,
|
||||
void *out,
|
||||
size_t max,
|
||||
size_t *nr_read)
|
||||
@@ -14,25 +15,35 @@ kern_status_t xpc_buffer_read(
|
||||
return KERN_BAD_STATE;
|
||||
}
|
||||
|
||||
size_t to_read = max;
|
||||
if (to_read > buf->buf_len) {
|
||||
to_read = buf->buf_len;
|
||||
if (offset >= buf->buf_len) {
|
||||
if (nr_read) {
|
||||
*nr_read = 0;
|
||||
}
|
||||
|
||||
return KERN_OK;
|
||||
}
|
||||
|
||||
kern_status_t status
|
||||
= 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) {
|
||||
return status;
|
||||
}
|
||||
|
||||
/* TODO */
|
||||
*nr_read = to_read;
|
||||
|
||||
return KERN_OK;
|
||||
}
|
||||
|
||||
kern_status_t xpc_buffer_write(
|
||||
xpc_buffer_t *buf,
|
||||
size_t offset,
|
||||
const void *in,
|
||||
size_t len,
|
||||
size_t *nr_written)
|
||||
@@ -41,9 +52,17 @@ kern_status_t xpc_buffer_write(
|
||||
return KERN_BAD_STATE;
|
||||
}
|
||||
|
||||
if (offset >= buf->buf_max) {
|
||||
if (nr_written) {
|
||||
*nr_written = 0;
|
||||
}
|
||||
|
||||
return KERN_OK;
|
||||
}
|
||||
|
||||
size_t to_write = len;
|
||||
if (to_write > buf->buf_max) {
|
||||
to_write = buf->buf_max;
|
||||
if (offset + to_write > buf->buf_max) {
|
||||
to_write = buf->buf_max - offset;
|
||||
}
|
||||
|
||||
if (!(buf->buf_flags & XPC_BUFFER_F_REMOTE)) {
|
||||
@@ -54,8 +73,70 @@ kern_status_t xpc_buffer_write(
|
||||
|
||||
return xpc_msg_write(
|
||||
buf->buf_origin,
|
||||
buf->buf_offset,
|
||||
buf->buf_offset + offset,
|
||||
in,
|
||||
to_write,
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#ifndef XPC_BUFFER_H_
|
||||
#define XPC_BUFFER_H_
|
||||
|
||||
#include <mango/types.h>
|
||||
#include <stddef.h>
|
||||
#include <xpc/status.h>
|
||||
|
||||
@@ -71,13 +72,31 @@ typedef struct xpc_buffer {
|
||||
|
||||
extern xpc_status_t xpc_buffer_read(
|
||||
const xpc_buffer_t *s,
|
||||
size_t offset,
|
||||
void *out,
|
||||
size_t max,
|
||||
size_t *nr_read);
|
||||
extern xpc_status_t xpc_buffer_write(
|
||||
xpc_buffer_t *s,
|
||||
size_t offset,
|
||||
const void *in,
|
||||
size_t len,
|
||||
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
|
||||
|
||||
@@ -34,7 +34,8 @@ extern kern_status_t xpc_msg_read(
|
||||
const xpc_msg_t *msg,
|
||||
size_t offset,
|
||||
void *p,
|
||||
size_t count);
|
||||
size_t count,
|
||||
size_t *nr_read);
|
||||
extern kern_status_t xpc_msg_write(
|
||||
const xpc_msg_t *msg,
|
||||
size_t offset,
|
||||
@@ -42,6 +43,19 @@ extern kern_status_t xpc_msg_write(
|
||||
size_t count,
|
||||
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(
|
||||
const xpc_msg_t *msg,
|
||||
kern_iovec_t *iov,
|
||||
|
||||
@@ -89,17 +89,17 @@ kern_status_t xpc_msg_read(
|
||||
const xpc_msg_t *msg,
|
||||
size_t offset,
|
||||
void *p,
|
||||
size_t count)
|
||||
size_t count,
|
||||
size_t *nr_read)
|
||||
{
|
||||
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);
|
||||
nr_read);
|
||||
}
|
||||
|
||||
kern_status_t xpc_msg_write(
|
||||
@@ -119,6 +119,38 @@ kern_status_t xpc_msg_write(
|
||||
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(
|
||||
const xpc_msg_t *msg,
|
||||
kern_iovec_t *iov,
|
||||
|
||||
@@ -19,14 +19,12 @@ xpc_status_t xpc_string_read(
|
||||
}
|
||||
|
||||
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) {
|
||||
return status;
|
||||
}
|
||||
|
||||
out[to_read] = '\0';
|
||||
/* TODO */
|
||||
*nr_read = to_read;
|
||||
|
||||
return KERN_OK;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user