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(
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
return KERN_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
kern_status_t status
|
size_t to_read = max;
|
||||||
= xpc_msg_read(buf->buf_origin, buf->buf_offset, out, to_read);
|
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;
|
||||||
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user