mirror of
https://github.com/Mathewnd/Astral.git
synced 2026-11-01 15:08:21 +00:00
sockfs: support FIONBIO ioctl
This commit is contained in:
+16
-4
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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];
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
Reference in New Issue
Block a user