Skip to content

Commit d974bce

Browse files
authored
implement F_{GET,SET}FL for fcntl for sockets (#742)
This provides another way to get/set blocking-ness besides `ioctl`.
1 parent 4dc4a42 commit d974bce

4 files changed

Lines changed: 108 additions & 0 deletions

File tree

libc-bottom-half/sources/wasip2_tcp.c

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1237,6 +1237,25 @@ static int tcp_poll_finish(void *data, poll_state_t *state, short events) {
12371237
return 0;
12381238
}
12391239

1240+
static int tcp_fcntl_getfl(void *data) {
1241+
tcp_socket_t *socket = (tcp_socket_t *)data;
1242+
int flags = 0;
1243+
if (!socket->blocking) {
1244+
flags |= O_NONBLOCK;
1245+
}
1246+
return flags;
1247+
}
1248+
1249+
static int tcp_fcntl_setfl(void *data, int flags) {
1250+
tcp_socket_t *socket = (tcp_socket_t *)data;
1251+
if (flags & O_NONBLOCK) {
1252+
socket->blocking = false;
1253+
} else {
1254+
socket->blocking = true;
1255+
}
1256+
return 0;
1257+
}
1258+
12401259
static descriptor_vtable_t tcp_vtable = {
12411260
.free = tcp_free,
12421261

@@ -1259,6 +1278,9 @@ static descriptor_vtable_t tcp_vtable = {
12591278

12601279
.poll_register = tcp_poll_register,
12611280
.poll_finish = tcp_poll_finish,
1281+
1282+
.fcntl_getfl = tcp_fcntl_getfl,
1283+
.fcntl_setfl = tcp_fcntl_setfl,
12621284
};
12631285

12641286
#endif // __wasip2__

libc-bottom-half/sources/wasip2_udp.c

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#include <errno.h>
2+
#include <fcntl.h>
23
#include <limits.h>
34
#include <stdlib.h>
45
#include <string.h>
@@ -869,6 +870,25 @@ static int udp_poll_register(void *data, poll_state_t *state, short events) {
869870
return 0;
870871
}
871872

873+
static int udp_fcntl_getfl(void *data) {
874+
udp_socket_t *socket = (udp_socket_t *)data;
875+
int flags = 0;
876+
if (!socket->blocking) {
877+
flags |= O_NONBLOCK;
878+
}
879+
return flags;
880+
}
881+
882+
static int udp_fcntl_setfl(void *data, int flags) {
883+
udp_socket_t *socket = (udp_socket_t *)data;
884+
if (flags & O_NONBLOCK) {
885+
socket->blocking = false;
886+
} else {
887+
socket->blocking = true;
888+
}
889+
return 0;
890+
}
891+
872892
static descriptor_vtable_t udp_vtable = {
873893
.free = udp_free,
874894

@@ -885,6 +905,9 @@ static descriptor_vtable_t udp_vtable = {
885905
.setsockopt = udp_setsockopt,
886906

887907
.poll_register = udp_poll_register,
908+
909+
.fcntl_getfl = udp_fcntl_getfl,
910+
.fcntl_setfl = udp_fcntl_setfl,
888911
};
889912

890913
#endif // __wasip2__

test/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -317,6 +317,7 @@ if (NOT (WASI STREQUAL "p1"))
317317
add_wasilibc_test(sockets-nonblocking-udp.c NETWORK FAILP3)
318318
add_wasilibc_test(sockets-nonblocking-multiple.c NETWORK FAILP3)
319319
add_wasilibc_test(sockets-nonblocking-udp-multiple.c NETWORK FAILP3)
320+
add_wasilibc_test(sockets-fcntl.c NETWORK FAILP3)
320321

321322
# TODO: flaky tests
322323
# add_wasilibc_test(sockets-nonblocking.c NETWORK)

test/src/sockets-fcntl.c

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
#include "test.h"
2+
#include <errno.h>
3+
#include <fcntl.h>
4+
#include <sys/ioctl.h>
5+
#include <sys/socket.h>
6+
7+
#define TEST(c) \
8+
do { \
9+
errno = 0; \
10+
if (!(c)) \
11+
t_error("%s failed (errno = %d)\n", #c, errno); \
12+
} while (0)
13+
14+
#define TEST2(c) \
15+
do { \
16+
if (!(c)) \
17+
t_error("%s failed (errno = %d)\n", #c, errno); \
18+
} while (0)
19+
20+
#define ASSERT(c) \
21+
do { \
22+
if (!(c)) \
23+
t_error("%s failed\n", #c); \
24+
} while (0)
25+
26+
int main() {
27+
int types[2] = {SOCK_STREAM, SOCK_DGRAM};
28+
29+
for (int i = 0; i < 2; ++i) {
30+
errno = 0;
31+
int fd = socket(AF_INET, types[i], 0);
32+
TEST2(fd != -1);
33+
34+
{
35+
errno = 0;
36+
int flags = fcntl(fd, F_GETFL, 0);
37+
TEST2(flags != -1);
38+
ASSERT((flags & O_NONBLOCK) == 0);
39+
}
40+
41+
TEST(fcntl(fd, F_SETFL, O_NONBLOCK) != -1);
42+
43+
{
44+
errno = 0;
45+
int flags = fcntl(fd, F_GETFL, 0);
46+
TEST2(flags != -1);
47+
ASSERT((flags & O_NONBLOCK) != 0);
48+
}
49+
50+
int zero = 0;
51+
TEST(ioctl(fd, FIONBIO, &zero) != -1);
52+
53+
{
54+
errno = 0;
55+
int flags = fcntl(fd, F_GETFL, 0);
56+
TEST2(flags != -1);
57+
ASSERT((flags & O_NONBLOCK) == 0);
58+
}
59+
}
60+
61+
return t_status;
62+
}

0 commit comments

Comments
 (0)