net: Support ioctl FIONBIO to set non-blocking
This commit is contained in:
parent
df25724fcc
commit
b8b69255e3
@ -35,6 +35,7 @@ typedef struct SockData {
|
|||||||
|
|
||||||
size_t unread;
|
size_t unread;
|
||||||
char * buf;
|
char * buf;
|
||||||
|
int nonblocking;
|
||||||
} sock_t;
|
} sock_t;
|
||||||
|
|
||||||
void net_sock_alert(sock_t * sock);
|
void net_sock_alert(sock_t * sock);
|
||||||
|
@ -14,4 +14,5 @@
|
|||||||
|
|
||||||
#define IOCTL_PACKETFS_QUEUED 0x5050
|
#define IOCTL_PACKETFS_QUEUED 0x5050
|
||||||
|
|
||||||
|
#define FIONBIO 0x4e424c4b
|
||||||
|
|
||||||
|
@ -207,6 +207,8 @@ static long sock_icmp_recv(sock_t * sock, struct msghdr * msg, int flags) {
|
|||||||
}
|
}
|
||||||
if (msg->msg_iovlen == 0) return 0;
|
if (msg->msg_iovlen == 0) return 0;
|
||||||
|
|
||||||
|
if (!sock->rx_queue->length && sock->nonblocking) return -EAGAIN;
|
||||||
|
|
||||||
char * packet = net_sock_get(sock);
|
char * packet = net_sock_get(sock);
|
||||||
if (!packet) return -EINTR;
|
if (!packet) return -EINTR;
|
||||||
size_t packet_size = *(size_t*)packet - sizeof(struct ipv4_packet);
|
size_t packet_size = *(size_t*)packet - sizeof(struct ipv4_packet);
|
||||||
@ -536,6 +538,8 @@ static long sock_udp_recv(sock_t * sock, struct msghdr * msg, int flags) {
|
|||||||
}
|
}
|
||||||
if (msg->msg_iovlen == 0) return 0;
|
if (msg->msg_iovlen == 0) return 0;
|
||||||
|
|
||||||
|
if (!sock->rx_queue->length && sock->nonblocking) return -EAGAIN;
|
||||||
|
|
||||||
char * packet = net_sock_get(sock);
|
char * packet = net_sock_get(sock);
|
||||||
if (!packet) return -EINTR;
|
if (!packet) return -EINTR;
|
||||||
struct ipv4_packet * data = (struct ipv4_packet*)(packet + sizeof(size_t));
|
struct ipv4_packet * data = (struct ipv4_packet*)(packet + sizeof(size_t));
|
||||||
@ -698,6 +702,8 @@ static long sock_tcp_recv(sock_t * sock, struct msghdr * msg, int flags) {
|
|||||||
return 0; /* EOF */
|
return 0; /* EOF */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!sock->rx_queue->length && sock->nonblocking) return -EAGAIN;
|
||||||
|
|
||||||
while (!sock->rx_queue->length) {
|
while (!sock->rx_queue->length) {
|
||||||
process_wait_nodes((process_t *)this_core->current_process, (fs_node_t*[]){(fs_node_t*)sock,NULL}, 200);
|
process_wait_nodes((process_t *)this_core->current_process, (fs_node_t*[]){(fs_node_t*)sock,NULL}, 200);
|
||||||
}
|
}
|
||||||
|
@ -105,6 +105,18 @@ void sock_generic_close(fs_node_t *node) {
|
|||||||
printf("net: socket closed\n");
|
printf("net: socket closed\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int sock_generic_ioctl(fs_node_t * node, unsigned long request, void * argp) {
|
||||||
|
sock_t * sock = (sock_t*)node;
|
||||||
|
switch (request) {
|
||||||
|
case FIONBIO: {
|
||||||
|
if (!mmu_validate_user_pointer(argp, sizeof(int), 0)) return -EFAULT;
|
||||||
|
sock->nonblocking = (!!*(int*)argp);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
sock_t * net_sock_create(void) {
|
sock_t * net_sock_create(void) {
|
||||||
sock_t * sock = calloc(sizeof(struct SockData),1);
|
sock_t * sock = calloc(sizeof(struct SockData),1);
|
||||||
sock->_fnode.flags = FS_SOCKET; /* uh, FS_SOCKET? */
|
sock->_fnode.flags = FS_SOCKET; /* uh, FS_SOCKET? */
|
||||||
@ -113,6 +125,7 @@ sock_t * net_sock_create(void) {
|
|||||||
sock->_fnode.selectcheck = sock_generic_check;
|
sock->_fnode.selectcheck = sock_generic_check;
|
||||||
sock->_fnode.selectwait = sock_generic_wait;
|
sock->_fnode.selectwait = sock_generic_wait;
|
||||||
sock->_fnode.close = sock_generic_close;
|
sock->_fnode.close = sock_generic_close;
|
||||||
|
sock->_fnode.ioctl = sock_generic_ioctl;
|
||||||
sock->alert_wait = list_create("socket alert wait", sock);
|
sock->alert_wait = list_create("socket alert wait", sock);
|
||||||
sock->rx_wait = list_create("socket rx wait", sock);
|
sock->rx_wait = list_create("socket rx wait", sock);
|
||||||
sock->rx_queue = list_create("socket rx queue", sock);
|
sock->rx_queue = list_create("socket rx queue", sock);
|
||||||
|
Loading…
Reference in New Issue
Block a user