Skip to content

Commit

Permalink
ipc: socket accept()
Browse files Browse the repository at this point in the history
  • Loading branch information
jewelcodes committed Sep 7, 2024
1 parent 5d1a968 commit a910e3e
Showing 1 changed file with 60 additions and 1 deletion.
61 changes: 60 additions & 1 deletion src/ipc/connection.c
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ int listen(Thread *t, int sd, int backlog) {

if(backlog > 0) sock->backlogMax = backlog;
else sock->backlogMax = SOCKET_DEFAULT_BACKLOG;

sock->backlog = calloc(backlog, sizeof(SocketDescriptor *));
if(!sock->backlog) {
socketRelease();
Expand All @@ -83,3 +83,62 @@ int listen(Thread *t, int sd, int backlog) {
socketRelease();
return 0;
}

/* accept(): accepts an incoming socket connection
* this function does NOT block at the kernel level - the syscall dispatcher
* will take care of blocking if the socket is not set to be non-blocking
* params: t - calling thread, NULL for kernel threads
* params: sd - socket descriptor
* params: addr - buffer to store peer's address
* params: len - length of the buffer on input, length of data stored on output
* returns: positive socket descriptor on success, negative error code on fail
*/

int accept(Thread *t, int sd, struct sockaddr *addr, socklen_t *len) {
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 *listener = (SocketDescriptor *)p->io[sd].data;
if(!listener->listener || !listener->backlog || !listener->backlogMax)
return -EINVAL; // socket is not listening

if(!listener->backlogCount)
return -EWOULDBLOCK; // socket has no incoming queue

socketLock();

// create a new connected socket
IODescriptor *iod = NULL;
int connectedSocket = openIO(p, (void **) &iod);
if((connectedSocket < 0) || !iod) {
socketRelease();
return -EMFILE;
}

iod->type = IO_SOCKET;
iod->flags = p->io[sd].flags;
iod->data = calloc(1, sizeof(SocketDescriptor));
if(!iod->data) {
socketRelease();
closeIO(p, iod);
return -ENOMEM;
}

// copy the self address
SocketDescriptor *self = (SocketDescriptor *)iod->data;
memcpy(&self->address, &listener->address, sizeof(struct sockaddr));
self->type = listener->type;
self->protocol = listener->protocol;

// and assign the peer address
self->peer = listener->backlog[0]; // TODO: is this always FIFO?
memmove(&listener->backlog[0], &listener->backlog[1], (listener->backlogMax - 1) * sizeof(SocketDescriptor *));

socketRelease();
return connectedSocket;
}

0 comments on commit a910e3e

Please sign in to comment.