Skip to content

Commit 6593687

Browse files
dicejbadeend
andauthored
add wasip2 implementations of more socket APIs (#482)
This adds `wasm32-wasip2` implementations of `shutdown`, `getsockopt`, and `setsockopt`. It also extends the existing `ioctl` implementation to handle both p1 and p2 file descriptors since we can't know until runtime which kind we have. Once we've moved `wasm32-wasip2` fully to WASI 0.2 and remove the need for the p1 adapter, we'll be able to switch to separate p1 and p2 `ioctl` implementations. Signed-off-by: Joel Dice <joel.dice@fermyon.com> Co-authored-by: Dave Bakker <github@davebakker.io>
1 parent f493dc2 commit 6593687

5 files changed

Lines changed: 832 additions & 2 deletions

File tree

Makefile

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,9 @@ LIBC_BOTTOM_HALF_OMIT_SOURCES := \
8989
$(LIBC_BOTTOM_HALF_SOURCES)/sockets_utils.c \
9090
$(LIBC_BOTTOM_HALF_SOURCES)/bind.c \
9191
$(LIBC_BOTTOM_HALF_SOURCES)/listen.c \
92-
$(LIBC_BOTTOM_HALF_SOURCES)/accept-wasip2.c
92+
$(LIBC_BOTTOM_HALF_SOURCES)/accept-wasip2.c \
93+
$(LIBC_BOTTOM_HALF_SOURCES)/shutdown.c \
94+
$(LIBC_BOTTOM_HALF_SOURCES)/sockopt.c
9395
LIBC_BOTTOM_HALF_ALL_SOURCES := $(filter-out $(LIBC_BOTTOM_HALF_OMIT_SOURCES),$(LIBC_BOTTOM_HALF_ALL_SOURCES))
9496
# Omit p2-specific headers from include-all.c test.
9597
INCLUDE_ALL_CLAUSES := -not -name wasip2.h -not -name descriptor_table.h
@@ -100,6 +102,8 @@ ifeq ($(WASI_SNAPSHOT), p2)
100102
LIBC_BOTTOM_HALF_OMIT_SOURCES := \
101103
$(LIBC_BOTTOM_HALF_CLOUDLIBC_SRC)/libc/sys/socket/send.c \
102104
$(LIBC_BOTTOM_HALF_CLOUDLIBC_SRC)/libc/sys/socket/recv.c \
105+
$(LIBC_BOTTOM_HALF_CLOUDLIBC_SRC)/libc/sys/socket/shutdown.c \
106+
$(LIBC_BOTTOM_HALF_CLOUDLIBC_SRC)/libc/sys/socket/getsockopt.c \
103107
$(LIBC_BOTTOM_HALF_SOURCES)/accept-wasip1.c
104108
LIBC_BOTTOM_HALF_ALL_SOURCES := $(filter-out $(LIBC_BOTTOM_HALF_OMIT_SOURCES),$(LIBC_BOTTOM_HALF_ALL_SOURCES))
105109
endif

expected/wasm32-wasip2/defined-symbols.txt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
NS_PER_S
12
_CLOCK_MONOTONIC
23
_CLOCK_REALTIME
34
_Exit
@@ -1111,6 +1112,7 @@ setenv
11111112
setkey
11121113
setlinebuf
11131114
setlocale
1115+
setsockopt
11141116
setstate
11151117
setvbuf
11161118
shutdown
@@ -1243,6 +1245,7 @@ tcp_bind
12431245
tcp_borrow_tcp_socket
12441246
tcp_create_socket_create_tcp_socket
12451247
tcp_create_socket_result_own_tcp_socket_error_code_free
1248+
tcp_getsockopt
12461249
tcp_ip_socket_address_free
12471250
tcp_listen
12481251
tcp_method_tcp_socket_accept
@@ -1282,6 +1285,8 @@ tcp_result_u32_error_code_free
12821285
tcp_result_u64_error_code_free
12831286
tcp_result_u8_error_code_free
12841287
tcp_result_void_error_code_free
1288+
tcp_setsockopt
1289+
tcp_shutdown
12851290
tcp_tcp_socket_drop_borrow
12861291
tcp_tcp_socket_drop_own
12871292
tdelete
@@ -1332,6 +1337,7 @@ udp_borrow_outgoing_datagram_stream
13321337
udp_borrow_udp_socket
13331338
udp_create_socket_create_udp_socket
13341339
udp_create_socket_result_own_udp_socket_error_code_free
1340+
udp_getsockopt
13351341
udp_incoming_datagram_free
13361342
udp_incoming_datagram_stream_drop_borrow
13371343
udp_incoming_datagram_stream_drop_own
@@ -1367,6 +1373,8 @@ udp_result_tuple2_own_incoming_datagram_stream_own_outgoing_datagram_stream_erro
13671373
udp_result_u64_error_code_free
13681374
udp_result_u8_error_code_free
13691375
udp_result_void_error_code_free
1376+
udp_setsockopt
1377+
udp_shutdown
13701378
udp_udp_socket_drop_borrow
13711379
udp_udp_socket_drop_own
13721380
uname

libc-bottom-half/cloudlibc/src/libc/sys/ioctl/ioctl.c

Lines changed: 56 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,66 @@
44

55
#include <sys/ioctl.h>
66

7-
#include <wasi/api.h>
87
#include <errno.h>
98
#include <stdarg.h>
109

10+
#include <wasi/api.h>
11+
#ifdef __wasilibc_use_wasip2
12+
#include <wasi/descriptor_table.h>
13+
#endif
14+
1115
int ioctl(int fildes, int request, ...) {
16+
#ifdef __wasilibc_use_wasip2
17+
descriptor_table_entry_t *entry;
18+
if (descriptor_table_get_ref(fildes, &entry)) {
19+
switch (entry->tag) {
20+
case DESCRIPTOR_TABLE_ENTRY_TCP_SOCKET: {
21+
tcp_socket_t *socket = &entry->tcp_socket;
22+
switch (request) {
23+
case FIONBIO: {
24+
va_list ap;
25+
va_start(ap, request);
26+
socket->blocking = *va_arg(ap, const int *) ==
27+
0;
28+
va_end(ap);
29+
30+
return 0;
31+
}
32+
33+
default:
34+
// TODO wasi-sockets: anything else we should support?
35+
errno = EINVAL;
36+
return -1;
37+
}
38+
}
39+
40+
case DESCRIPTOR_TABLE_ENTRY_UDP_SOCKET: {
41+
udp_socket_t *socket = &entry->udp_socket;
42+
switch (request) {
43+
case FIONBIO: {
44+
va_list ap;
45+
va_start(ap, request);
46+
socket->blocking = *va_arg(ap, const int *) ==
47+
0;
48+
va_end(ap);
49+
50+
return 0;
51+
}
52+
53+
default:
54+
// TODO wasi-sockets: anything else we should support?
55+
errno = EINVAL;
56+
return -1;
57+
}
58+
}
59+
60+
default:
61+
errno = ENOPROTOOPT;
62+
return -1;
63+
}
64+
}
65+
#endif // __wasilibc_use_wasip2
66+
1267
switch (request) {
1368
case FIONREAD: {
1469
// Poll the file descriptor to determine how many bytes can be read.
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
#include <sys/socket.h>
2+
3+
#include <errno.h>
4+
5+
#include <wasi/api.h>
6+
#include <wasi/descriptor_table.h>
7+
#include <wasi/sockets_utils.h>
8+
9+
int tcp_shutdown(tcp_socket_t *socket, int posix_how)
10+
{
11+
tcp_shutdown_type_t wasi_how;
12+
switch (posix_how) {
13+
case SHUT_RD:
14+
wasi_how = TCP_SHUTDOWN_TYPE_RECEIVE;
15+
break;
16+
case SHUT_WR:
17+
wasi_how = TCP_SHUTDOWN_TYPE_SEND;
18+
break;
19+
case SHUT_RDWR:
20+
wasi_how = TCP_SHUTDOWN_TYPE_BOTH;
21+
break;
22+
default:
23+
errno = EINVAL;
24+
return -1;
25+
}
26+
27+
tcp_socket_state_connected_t connection;
28+
if (socket->state.tag == TCP_SOCKET_STATE_CONNECTED) {
29+
connection = socket->state.connected;
30+
} else {
31+
errno = ENOTCONN;
32+
return -1;
33+
}
34+
35+
network_error_code_t error;
36+
tcp_borrow_tcp_socket_t socket_borrow =
37+
tcp_borrow_tcp_socket(socket->socket);
38+
if (!tcp_method_tcp_socket_shutdown(socket_borrow, wasi_how, &error)) {
39+
errno = __wasi_sockets_utils__map_error(error);
40+
return -1;
41+
}
42+
43+
if (posix_how == SHUT_RD || posix_how == SHUT_RDWR) {
44+
// TODO wasi-sockets: drop input stream (if not already). And
45+
// update `recv` to take dropped input streams into account.
46+
}
47+
48+
if (posix_how == SHUT_WR || posix_how == SHUT_RDWR) {
49+
// TODO wasi-sockets: drop output stream (if not already). And
50+
// update `send` to take dropped output streams into account.
51+
}
52+
53+
return 0;
54+
}
55+
56+
int udp_shutdown(udp_socket_t *socket, int posix_how)
57+
{
58+
// UDP has nothing to shut down.
59+
errno = EOPNOTSUPP;
60+
return -1;
61+
}
62+
63+
int shutdown(int socket, int how)
64+
{
65+
descriptor_table_entry_t *entry;
66+
if (!descriptor_table_get_ref(socket, &entry)) {
67+
errno = EBADF;
68+
return -1;
69+
}
70+
71+
switch (entry->tag) {
72+
case DESCRIPTOR_TABLE_ENTRY_TCP_SOCKET:
73+
return tcp_shutdown(&entry->tcp_socket, how);
74+
case DESCRIPTOR_TABLE_ENTRY_UDP_SOCKET:
75+
return udp_shutdown(&entry->udp_socket, how);
76+
default:
77+
errno = EOPNOTSUPP;
78+
return -1;
79+
}
80+
}

0 commit comments

Comments
 (0)