From 7617cd47555c634e76ca27457d3ad49e0d05419f Mon Sep 17 00:00:00 2001 From: jewelcodes Date: Sat, 7 Sep 2024 17:46:34 -0400 Subject: [PATCH] ipc: socket recv() --- src/ipc/sockio.c | 68 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 67 insertions(+), 1 deletion(-) diff --git a/src/ipc/sockio.c b/src/ipc/sockio.c index f9b86bb..8763cf1 100644 --- a/src/ipc/sockio.c +++ b/src/ipc/sockio.c @@ -44,12 +44,14 @@ ssize_t send(Thread *t, int sd, const void *buffer, size_t len, int flags) { if(family == AF_UNIX || family == AF_LOCAL) { // simply append to the peer's inbound list - void **newlist = realloc(peer->inbound, (peer->inboundCount + 1) * sizeof(void *)); + void **newlist = realloc(peer->inbound, (peer->inboundCount+1) * sizeof(void *)); if(!newlist) { socketRelease(); return -ENOBUFS; } + size_t *newlen = realloc(peer->inboundLen, (peer->inboundCount+1) * sizeof(size_t)); + void *message = malloc(len); if(!message) { free(newlist); @@ -60,8 +62,10 @@ ssize_t send(Thread *t, int sd, const void *buffer, size_t len, int flags) { // and send memcpy(message, buffer, len); newlist[peer->inboundCount] = message; + newlen[peer->inboundCount] = len; peer->inboundCount++; peer->inbound = newlist; + peer->inboundLen = newlen; socketRelease(); return len; @@ -71,3 +75,65 @@ ssize_t send(Thread *t, int sd, const void *buffer, size_t len, int flags) { return -ENOTCONN; } } + +/* recv(): receives a message from a socket connection + * params: t - calling thread + * params: sd - socket descriptor + * params: buffer - buffer to store message + * params: len - maximum size of the buffer + * params: flags - optional flags for the request + * returns: positive number of bytes received, negative error code on fail + */ + +ssize_t recv(Thread *t, int sd, void *buffer, size_t len, int flags) { + Process *p; + if(t) p = getProcess(t->pid); + else p = getProcess(getPid()); + if(!p) return -ESRCH; + + if(!p->io[sd].valid || !p->io[sd].data || (p->io[sd].type != IO_SOCKET)) + return -ENOTSOCK; + + SocketDescriptor *self = (SocketDescriptor*) p->io[sd].data; + if(!self->peer) return -EDESTADDRREQ; // not in connection mode + + sa_family_t family = self->address.sa_family; + if(!self->inboundCount || !self->inbound || !self->inboundLen) + return -EWOULDBLOCK; // no messages available + + socketLock(); + + if(family == AF_UNIX || family == AF_LOCAL) { + // copy from the inbound list + void *message = self->inbound[0]; // FIFO + size_t truelen = self->inboundLen[0]; + + if(!message) { + socketRelease(); + return -EWOULDBLOCK; + } + + if(truelen > len) truelen = len; // truncate longer messages + memcpy(buffer, message, truelen); + + // and remove the received message from the queue + free(message); + + self->inboundCount--; + if(!self->inboundCount) { + free(self->inbound); + free(self->inboundLen); + } else { + memmove(&self->inbound[0], &self->inbound[1], self->inboundCount * sizeof(void *)); + memmove(&self->inboundLen[0], &self->inboundLen[1], self->inboundCount * sizeof(size_t)); + self->inbound = realloc(self->inbound, self->inboundCount * sizeof(void *)); + self->inboundLen = realloc(self->inboundLen, self->inboundCount * sizeof(void *)); + } + + return truelen; + } else { + /* TODO: handle other protocols in user space */ + socketRelease(); + return -ENOTCONN; + } +} \ No newline at end of file