diff --git a/src/fs/vfs.c b/src/fs/vfs.c index 05178a5e..93d12fd5 100644 --- a/src/fs/vfs.c +++ b/src/fs/vfs.c @@ -66,6 +66,9 @@ int vfs_write(int* error, vnode_t* node, void* buff, size_t count, size_t offset int type = GETTYPE(node->st.st_mode); + if(type == TYPE_SOCKET) + return socket_send(node->objdata, buff, count, 0, error); + if(type == TYPE_FIFO) return pipe_write(node->objdata, buff, count, error); diff --git a/src/include/kernel/socket.h b/src/include/kernel/socket.h index 14b12ee8..8b52ad91 100644 --- a/src/include/kernel/socket.h +++ b/src/include/kernel/socket.h @@ -28,6 +28,7 @@ typedef struct _socket_t{ struct _socket_t** backlog; event_t connectevent; // when the socket is listening and this is fired, someone used connect() on the socket event_t acceptevent; // when a socket is waiting for a connection to be accepted, it sleeps on this + event_t dataevent; // fired when data is written to/read from the ring buffer int state; union { sockaddr_un addr_un; @@ -63,5 +64,5 @@ int socket_new(socket_t** returnptr, int family, int type, int protocol); int socket_bind(struct _socket_t* sock, void* addr, size_t addrlen); int socket_listen(struct _socket_t* sock, int backlog); int socket_accept(socket_t** peer, socket_t* sock, void* addr, size_t* addrlen); - +int socket_send(socket_t* socket, void* buff, size_t len, int flags, int* error); #endif diff --git a/src/include/kernel/unsocket.h b/src/include/kernel/unsocket.h index a121eb1e..9623c139 100644 --- a/src/include/kernel/unsocket.h +++ b/src/include/kernel/unsocket.h @@ -12,5 +12,5 @@ struct _socket_t; int unsocket_new(struct _socket_t** returnptr, int type, int protocol); int unsocket_bind(struct _socket_t* sock, sockaddr_un* addr, size_t addrlen); - +int unsocket_send(struct _socket_t* socket, void* buff, size_t len, int flags, int* error); #endif diff --git a/src/sys/socket.c b/src/sys/socket.c index 0ec17445..7c630127 100644 --- a/src/sys/socket.c +++ b/src/sys/socket.c @@ -83,3 +83,12 @@ int socket_accept(socket_t** peer, socket_t* sock, void* addr, size_t* addrlen){ return EINVAL; } } + +int socket_send(socket_t* socket, void* buff, size_t len, int flags, int* count){ + switch(socket->family){ + case AF_UNIX: + return unsocket_send(socket, buff, len, flags, count); + default: + return EINVAL; + } +} diff --git a/src/sys/unsocket.c b/src/sys/unsocket.c index 9f855825..6f9b95ec 100644 --- a/src/sys/unsocket.c +++ b/src/sys/unsocket.c @@ -211,3 +211,57 @@ int unsocket_accept(socket_t** peer, socket_t* sock, void* addr, size_t* addrlen return err; } + +int unsocket_send(socket_t* socket, void* buff, size_t len, int flags, int* error){ + + if(flags){ // right now no flags are supported + *error = EOPNOTSUPP; + return 0; + } + + + int err = 0; + int writec = 0; + + socket_t* peer = socket->peer; + + spinlock_acquire(&socket->lock); + spinlock_acquire(&peer->lock); + + if(socket->state != SOCKET_STATE_CONNECTED){ + *error = ENOTCONN; + goto _return; + } + + for(;;){ + arch_interrupt_disable(); + + writec = ringbuffer_write(&peer->buffer, buff, len); + + if(writec > 0){ + event_signal(&peer->dataevent, true); + break; + } + + spinlock_release(&peer->lock); + + if(event_wait(&peer->dataevent, true)){ + spinlock_acquire(&peer->lock); + writec = -1; + break; + } + + spinlock_acquire(&peer->lock); + + } + + *error = 0; + + _return: + + spinlock_release(&peer->lock); + spinlock_release(&socket->lock); + + return writec; + +}