sockfs: support FIONBIO ioctl

This commit is contained in:
Matheus
2026-04-23 12:09:35 -03:00
parent 789384249f
commit d46ee0f4ec
7 changed files with 34 additions and 14 deletions
+16 -4
View File
@@ -195,7 +195,7 @@ int sockfs_ioctl(vnode_t *node, unsigned long request, void *arg, int *result, c
free(dev); free(dev);
return e; return e;
} }
case FIONREAD: { case FIONREAD: {
socket_t *socket = SOCKFS_SOCKET_FROM_NODE(node); socket_t *socket = SOCKFS_SOCKET_FROM_NODE(node);
if (socket->ops->datacount == NULL) if (socket->ops->datacount == NULL)
return ENOTTY; return ENOTTY;
@@ -203,9 +203,21 @@ int sockfs_ioctl(vnode_t *node, unsigned long request, void *arg, int *result, c
int count = socket->ops->datacount(socket); int count = socket->ops->datacount(socket);
return USERCOPY_POSSIBLY_TO_USER(arg, &count, sizeof(int)); return USERCOPY_POSSIBLY_TO_USER(arg, &count, sizeof(int));
} }
default: case FIONBIO: {
printf("got unknown socket ioctl %lu\n", request); int nonblocking;
return ENOTTY; int e = USERCOPY_POSSIBLY_FROM_USER(&nonblocking, arg, sizeof(nonblocking));
if (e)
return e;
socket_t *socket = SOCKFS_SOCKET_FROM_NODE(node);
MUTEX_ACQUIRE(&socket->mutex);
socket->nonblocking = nonblocking != 0;
MUTEX_RELEASE(&socket->mutex);
return 0;
}
default:
printf("got unknown socket ioctl %lu\n", request);
return ENOTTY;
} }
return 0; return 0;
} }
+1
View File
@@ -165,6 +165,7 @@ typedef struct {
#define SIOCGIFHWADDR 0x8927 #define SIOCGIFHWADDR 0x8927
#define SIOCADDRT 0x890b #define SIOCADDRT 0x890b
#define FIONREAD 0x541B #define FIONREAD 0x541B
#define FIONBIO 0x5421
typedef struct { typedef struct {
char name[IFNAMSIZ]; char name[IFNAMSIZ];
+6
View File
@@ -7,6 +7,7 @@
#include <kernel/poll.h> #include <kernel/poll.h>
#include <kernel/usercopy.h> #include <kernel/usercopy.h>
#include <kernel/iovec.h> #include <kernel/iovec.h>
#include <stdbool.h>
#define SOCKET_STATE_UNBOUND 0 #define SOCKET_STATE_UNBOUND 0
#define SOCKET_STATE_BOUND 1 #define SOCKET_STATE_BOUND 1
@@ -27,6 +28,7 @@ typedef struct {
int type; int type;
int shutdown; int shutdown;
int error; int error;
bool nonblocking;
} socket_t; } socket_t;
typedef struct { typedef struct {
@@ -89,6 +91,10 @@ typedef struct {
#define SOCKET_TYPE_TCP 2 #define SOCKET_TYPE_TCP 2
#define SOCKFS_SOCKET_FROM_NODE(nodep) (((socketnode_t *)(nodep))->socket) #define SOCKFS_SOCKET_FROM_NODE(nodep) (((socketnode_t *)(nodep))->socket)
static inline bool socket_nonblocking(socket_t *socket, uintmax_t flags) {
return socket->nonblocking || (flags & V_FFLAGS_NONBLOCKING);
}
static inline int socket_recv(socket_t *socket, void *buffer, size_t size, uintmax_t flags, size_t *bytes_read) { static inline int socket_recv(socket_t *socket, void *buffer, size_t size, uintmax_t flags, size_t *bytes_read) {
iovec_iterator_t iovec_iterator; iovec_iterator_t iovec_iterator;
+5 -5
View File
@@ -342,7 +342,7 @@ static int localsock_send(socket_t *socket, sockdesc_t *sockdesc) {
break; break;
} }
if (sockdesc->flags & V_FFLAGS_NONBLOCKING) { if (socket_nonblocking(socket, sockdesc->flags)) {
error = EAGAIN; error = EAGAIN;
poll_leave(&desc); poll_leave(&desc);
poll_destroydesc(&desc); poll_destroydesc(&desc);
@@ -433,7 +433,7 @@ static int localsock_recv(socket_t *socket, sockdesc_t *sockdesc) {
} }
} }
if (flags & V_FFLAGS_NONBLOCKING) { if (socket_nonblocking(socket, flags)) {
error = EAGAIN; error = EAGAIN;
poll_leave(&desc); poll_leave(&desc);
poll_destroydesc(&desc); poll_destroydesc(&desc);
@@ -549,7 +549,7 @@ static int localsock_accept(socket_t *_server, socket_t *_clientconnection, sock
break; break;
} }
if (flags & V_FFLAGS_NONBLOCKING) { if (socket_nonblocking(&server->socket, flags)) {
error = EAGAIN; error = EAGAIN;
poll_leave(&desc); poll_leave(&desc);
poll_destroydesc(&desc); poll_destroydesc(&desc);
@@ -664,7 +664,7 @@ static int localsock_connect(socket_t *socket, sockaddr_t *addr, uintmax_t flags
break; break;
} }
if (flags & V_FFLAGS_NONBLOCKING) { if (socket_nonblocking(socket, flags)) {
error = EAGAIN; error = EAGAIN;
poll_leave(&desc); poll_leave(&desc);
poll_destroydesc(&desc); poll_destroydesc(&desc);
@@ -722,7 +722,7 @@ static int localsock_connect(socket_t *socket, sockaddr_t *addr, uintmax_t flags
// if nonblocking, return success. the userspace/whatever will // if nonblocking, return success. the userspace/whatever will
// poll() the client to know when they can send data or if the server gave up and closed // poll() the client to know when they can send data or if the server gave up and closed
if (flags & V_FFLAGS_NONBLOCKING) { if (socket_nonblocking(socket, flags)) {
error = 0; error = 0;
goto leave; goto leave;
} }
+1
View File
@@ -17,6 +17,7 @@ socket_t *socket_create(int type) {
socket->state = SOCKET_STATE_UNBOUND; socket->state = SOCKET_STATE_UNBOUND;
MUTEX_INIT(&socket->mutex); MUTEX_INIT(&socket->mutex);
socket->type = type; socket->type = type;
socket->nonblocking = false;
return socket; return socket;
} }
+4 -4
View File
@@ -1294,7 +1294,7 @@ static int tcp_send(socket_t *socket, sockdesc_t *sockdesc) {
break; break;
} }
if (revents & V_FFLAGS_NONBLOCKING) { if (socket_nonblocking(socket, sockdesc->flags)) {
poll_leave(&polldesc); poll_leave(&polldesc);
poll_destroydesc(&polldesc); poll_destroydesc(&polldesc);
error = EAGAIN; error = EAGAIN;
@@ -1374,7 +1374,7 @@ static int tcp_recv(socket_t *socket, sockdesc_t *sockdesc) {
} }
} }
if (flags & V_FFLAGS_NONBLOCKING) { if (socket_nonblocking(socket, flags)) {
error = EAGAIN; error = EAGAIN;
poll_leave(&desc); poll_leave(&desc);
poll_destroydesc(&desc); poll_destroydesc(&desc);
@@ -1587,7 +1587,7 @@ static int tcp_connect(socket_t *socket, sockaddr_t *addr, uintmax_t flags, cred
tcpsocket->tcb = tcb; tcpsocket->tcb = tcb;
} }
if (flags & V_FFLAGS_NONBLOCKING) { if (socket_nonblocking(socket, flags)) {
error = EINPROGRESS; error = EINPROGRESS;
goto cleanup; goto cleanup;
} }
@@ -1707,7 +1707,7 @@ static int tcp_accept(socket_t *server, socket_t *client, sockaddr_t *addr, uint
break; break;
} }
if (flags & V_FFLAGS_NONBLOCKING) { if (socket_nonblocking(server, flags)) {
error = EAGAIN; error = EAGAIN;
poll_leave(&desc); poll_leave(&desc);
poll_destroydesc(&desc); poll_destroydesc(&desc);
+1 -1
View File
@@ -242,7 +242,7 @@ static int udp_recv(socket_t *socket, sockdesc_t *sockdesc) {
break; break;
} }
if (flags & V_FFLAGS_NONBLOCKING) { if (socket_nonblocking(socket, flags)) {
e = EAGAIN; e = EAGAIN;
poll_leave(&desc); poll_leave(&desc);
poll_destroydesc(&desc); poll_destroydesc(&desc);