From e8bbfd3221049ed41d5bbcfd741da4375c79150f Mon Sep 17 00:00:00 2001 From: Kevin Lange Date: Wed, 16 Apr 2014 18:29:49 -0700 Subject: [PATCH] Add an ioctl to query available pex data --- modules/packetfs.c | 25 ++++++++++++++++++ toolchain/patches/newlib/toaru/sys/ioctl.h | 2 ++ userspace/lib/pex.c | 4 +++ userspace/lib/pex.h | 1 + userspace/lib/yutani.c | 11 ++++++++ userspace/lib/yutani.h | 2 ++ userspace/tests/test-pex.c | 30 ++++++++++++++++++++++ 7 files changed, 75 insertions(+) diff --git a/modules/packetfs.c b/modules/packetfs.c index 9cf01c62..d755f12d 100644 --- a/modules/packetfs.c +++ b/modules/packetfs.c @@ -3,6 +3,7 @@ #include #include #include +#include #define MAX_PACKET_SIZE 1024 @@ -132,6 +133,17 @@ static uint32_t write_server(fs_node_t * node, uint32_t offset, uint32_t size, u return send_to_client(p, head->target, size - sizeof(header_t), head->data); } +static int ioctl_server(fs_node_t * node, int request, void * argp) { + pex_ex_t * p = (pex_ex_t *)node->device; + + switch (request) { + case IOCTL_PACKETFS_QUEUED: + return pipe_size(p->server_pipe); + default: + return -1; + } +} + static uint32_t read_client(fs_node_t * node, uint32_t offset, uint32_t size, uint8_t * buffer) { pex_client_t * c = (pex_client_t *)node->inode; assert(c->parent == node->device); @@ -173,6 +185,17 @@ static uint32_t write_client(fs_node_t * node, uint32_t offset, uint32_t size, u return size; } +static int ioctl_client(fs_node_t * node, int request, void * argp) { + pex_client_t * c = (pex_client_t *)node->inode; + + switch (request) { + case IOCTL_PACKETFS_QUEUED: + return pipe_size(c->pipe); + default: + return -1; + } +} + static void open_pex(fs_node_t * node, unsigned int flags) { pex_ex_t * t = (pex_ex_t *)(node->device); @@ -184,6 +207,7 @@ static void open_pex(fs_node_t * node, unsigned int flags) { /* Set up the server side */ node->read = read_server; node->write = write_server; + node->ioctl = ioctl_server; debug_print(INFO, "[pex] Server launched: %s", t->name); debug_print(INFO, "fs_node = 0x%x", node); } else if (!(flags & O_CREAT)) { @@ -192,6 +216,7 @@ static void open_pex(fs_node_t * node, unsigned int flags) { node->read = read_client; node->write = write_client; + node->ioctl = ioctl_client; list_insert(t->clients, client); diff --git a/toolchain/patches/newlib/toaru/sys/ioctl.h b/toolchain/patches/newlib/toaru/sys/ioctl.h index 810964d7..74d9c018 100644 --- a/toolchain/patches/newlib/toaru/sys/ioctl.h +++ b/toolchain/patches/newlib/toaru/sys/ioctl.h @@ -9,4 +9,6 @@ #define IOCTL_DTYPE_FILE 1 #define IOCTL_DTYPE_TTY 2 +#define IOCTL_PACKETFS_QUEUED 0x5050 + #endif diff --git a/userspace/lib/pex.c b/userspace/lib/pex.c index 19e67ce4..f6ff6d0b 100644 --- a/userspace/lib/pex.c +++ b/userspace/lib/pex.c @@ -5,6 +5,7 @@ #include #include #include +#include #include "pex.h" @@ -51,3 +52,6 @@ FILE * pex_bind(char * target) { return out; } +size_t pex_query(FILE * sock) { + return ioctl(fileno(sock), IOCTL_PACKETFS_QUEUED, NULL); +} diff --git a/userspace/lib/pex.h b/userspace/lib/pex.h index 1b2bcb8d..d6cf7426 100644 --- a/userspace/lib/pex.h +++ b/userspace/lib/pex.h @@ -23,6 +23,7 @@ size_t pex_listen(FILE * sock, pex_packet_t * packet); size_t pex_reply(FILE * sock, size_t size, char * blob); size_t pex_recv(FILE * sock, char * blob); +size_t pex_query(FILE * sock); FILE * pex_bind(char * target); FILE * pex_connect(char * target); diff --git a/userspace/lib/yutani.c b/userspace/lib/yutani.c index 8ecd0b51..4871c565 100644 --- a/userspace/lib/yutani.c +++ b/userspace/lib/yutani.c @@ -29,6 +29,10 @@ yutani_msg_t * yutani_wait_for(yutani_t * y, uint32_t type) { } while (1); /* XXX: (!y->abort) */ } +size_t yutani_query(yutani_t * y) { + return pex_query(y->sock); +} + yutani_msg_t * yutani_poll(yutani_t * y) { yutani_msg_t * out; size_t size; @@ -42,6 +46,13 @@ yutani_msg_t * yutani_poll(yutani_t * y) { return out; } +yutani_msg_t * yutani_poll_async(yutani_t * y) { + if (yutani_query(y) > 0) { + return yutani_poll(y); + } + return NULL; +} + yutani_msg_t * yutani_msg_build_hello(void) { size_t s = sizeof(struct yutani_message); yutani_msg_t * msg = malloc(s); diff --git a/userspace/lib/yutani.h b/userspace/lib/yutani.h index db2c4302..5cbc23fc 100644 --- a/userspace/lib/yutani.h +++ b/userspace/lib/yutani.h @@ -164,6 +164,8 @@ typedef struct { yutani_msg_t * yutani_wait_for(yutani_t * y, uint32_t type); yutani_msg_t * yutani_poll(yutani_t * y); +yutani_msg_t * yutani_poll_async(yutani_t * y); +size_t yutani_query(yutani_t * y); yutani_msg_t * yutani_msg_build_hello(void); yutani_msg_t * yutani_msg_build_welcome(uint32_t width, uint32_t height); diff --git a/userspace/tests/test-pex.c b/userspace/tests/test-pex.c index f0f08b42..4f2192ef 100644 --- a/userspace/tests/test-pex.c +++ b/userspace/tests/test-pex.c @@ -14,6 +14,15 @@ int main(int argc, char * argv[]) { char * foo = "Hello World!"; pex_reply(client, strlen(foo)+1, foo); + size_t query_result; + + query_result = pex_query(server); + if (query_result < 1) { + FAIL("Expected pex_query to return something > 0, got %d", query_result); + } else { + PASS("."); + } + pex_packet_t * p = calloc(PACKET_SIZE, 1); pex_listen(server, p); @@ -27,9 +36,30 @@ int main(int argc, char * argv[]) { free(p); + query_result = pex_query(server); + if (query_result != 0) { + FAIL("Expected pex_query to return 0, got %d", query_result); + } else { + PASS("."); + } + + query_result = pex_query(client); + if (query_result != 0) { + FAIL("Expected pex_query to return 0, got %d", query_result); + } else { + PASS("."); + } + char * foo2 = "Hello everyone!\n"; pex_broadcast(server, strlen(foo2)+1, foo2); + query_result = pex_query(client); + if (query_result < 1) { + FAIL("Expected pex_query to return something > 0, got %d", query_result); + } else { + PASS("."); + } + char out[MAX_PACKET_SIZE]; size_t size = pex_recv(client, out); if (!strcmp("Hello everyone!\n", out)) {