Skip to content

Commit

Permalink
add wasip2 implementations of more socket APIs
Browse files Browse the repository at this point in the history
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.

Co-authored-by: Dave Bakker <[email protected]>
Signed-off-by: Joel Dice <[email protected]>
  • Loading branch information
dicej and badeend committed Mar 13, 2024
1 parent f493dc2 commit 7204dc0
Show file tree
Hide file tree
Showing 5 changed files with 832 additions and 2 deletions.
6 changes: 5 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,9 @@ LIBC_BOTTOM_HALF_OMIT_SOURCES := \
$(LIBC_BOTTOM_HALF_SOURCES)/sockets_utils.c \
$(LIBC_BOTTOM_HALF_SOURCES)/bind.c \
$(LIBC_BOTTOM_HALF_SOURCES)/listen.c \
$(LIBC_BOTTOM_HALF_SOURCES)/accept-wasip2.c
$(LIBC_BOTTOM_HALF_SOURCES)/accept-wasip2.c \
$(LIBC_BOTTOM_HALF_SOURCES)/shutdown.c \
$(LIBC_BOTTOM_HALF_SOURCES)/sockopt.c
LIBC_BOTTOM_HALF_ALL_SOURCES := $(filter-out $(LIBC_BOTTOM_HALF_OMIT_SOURCES),$(LIBC_BOTTOM_HALF_ALL_SOURCES))
# Omit p2-specific headers from include-all.c test.
INCLUDE_ALL_CLAUSES := -not -name wasip2.h -not -name descriptor_table.h
Expand All @@ -100,6 +102,8 @@ ifeq ($(WASI_SNAPSHOT), p2)
LIBC_BOTTOM_HALF_OMIT_SOURCES := \
$(LIBC_BOTTOM_HALF_CLOUDLIBC_SRC)/libc/sys/socket/send.c \
$(LIBC_BOTTOM_HALF_CLOUDLIBC_SRC)/libc/sys/socket/recv.c \
$(LIBC_BOTTOM_HALF_CLOUDLIBC_SRC)/libc/sys/socket/shutdown.c \
$(LIBC_BOTTOM_HALF_CLOUDLIBC_SRC)/libc/sys/socket/getsockopt.c \
$(LIBC_BOTTOM_HALF_SOURCES)/accept-wasip1.c
LIBC_BOTTOM_HALF_ALL_SOURCES := $(filter-out $(LIBC_BOTTOM_HALF_OMIT_SOURCES),$(LIBC_BOTTOM_HALF_ALL_SOURCES))
endif
Expand Down
8 changes: 8 additions & 0 deletions expected/wasm32-wasip2/defined-symbols.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
NS_PER_S
_CLOCK_MONOTONIC
_CLOCK_REALTIME
_Exit
Expand Down Expand Up @@ -1111,6 +1112,7 @@ setenv
setkey
setlinebuf
setlocale
setsockopt
setstate
setvbuf
shutdown
Expand Down Expand Up @@ -1243,6 +1245,7 @@ tcp_bind
tcp_borrow_tcp_socket
tcp_create_socket_create_tcp_socket
tcp_create_socket_result_own_tcp_socket_error_code_free
tcp_getsockopt
tcp_ip_socket_address_free
tcp_listen
tcp_method_tcp_socket_accept
Expand Down Expand Up @@ -1282,6 +1285,8 @@ tcp_result_u32_error_code_free
tcp_result_u64_error_code_free
tcp_result_u8_error_code_free
tcp_result_void_error_code_free
tcp_setsockopt
tcp_shutdown
tcp_tcp_socket_drop_borrow
tcp_tcp_socket_drop_own
tdelete
Expand Down Expand Up @@ -1332,6 +1337,7 @@ udp_borrow_outgoing_datagram_stream
udp_borrow_udp_socket
udp_create_socket_create_udp_socket
udp_create_socket_result_own_udp_socket_error_code_free
udp_getsockopt
udp_incoming_datagram_free
udp_incoming_datagram_stream_drop_borrow
udp_incoming_datagram_stream_drop_own
Expand Down Expand Up @@ -1367,6 +1373,8 @@ udp_result_tuple2_own_incoming_datagram_stream_own_outgoing_datagram_stream_erro
udp_result_u64_error_code_free
udp_result_u8_error_code_free
udp_result_void_error_code_free
udp_setsockopt
udp_shutdown
udp_udp_socket_drop_borrow
udp_udp_socket_drop_own
uname
Expand Down
57 changes: 56 additions & 1 deletion libc-bottom-half/cloudlibc/src/libc/sys/ioctl/ioctl.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,66 @@

#include <sys/ioctl.h>

#include <wasi/api.h>
#include <errno.h>
#include <stdarg.h>

#include <wasi/api.h>
#ifdef __wasilibc_use_wasip2
#include <wasi/descriptor_table.h>
#endif

int ioctl(int fildes, int request, ...) {
#ifdef __wasilibc_use_wasip2
descriptor_table_entry_t *entry;
if (descriptor_table_get_ref(fildes, &entry)) {
switch (entry->tag) {
case DESCRIPTOR_TABLE_ENTRY_TCP_SOCKET: {
tcp_socket_t *socket = &entry->tcp_socket;
switch (request) {
case FIONBIO: {
va_list ap;
va_start(ap, request);
socket->blocking = *va_arg(ap, const int *) ==
0;
va_end(ap);

return 0;
}

default:
// TODO wasi-sockets: anything else we should support?
errno = EINVAL;
return -1;
}
}

case DESCRIPTOR_TABLE_ENTRY_UDP_SOCKET: {
udp_socket_t *socket = &entry->udp_socket;
switch (request) {
case FIONBIO: {
va_list ap;
va_start(ap, request);
socket->blocking = *va_arg(ap, const int *) ==
0;
va_end(ap);

return 0;
}

default:
// TODO wasi-sockets: anything else we should support?
errno = EINVAL;
return -1;
}
}

default:
errno = ENOPROTOOPT;
return -1;
}
}
#endif // __wasilibc_use_wasip2

switch (request) {
case FIONREAD: {
// Poll the file descriptor to determine how many bytes can be read.
Expand Down
80 changes: 80 additions & 0 deletions libc-bottom-half/sources/shutdown.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
#include <sys/socket.h>

#include <errno.h>

#include <wasi/api.h>
#include <wasi/descriptor_table.h>
#include <wasi/sockets_utils.h>

int tcp_shutdown(tcp_socket_t *socket, int posix_how)
{
tcp_shutdown_type_t wasi_how;
switch (posix_how) {
case SHUT_RD:
wasi_how = TCP_SHUTDOWN_TYPE_RECEIVE;
break;
case SHUT_WR:
wasi_how = TCP_SHUTDOWN_TYPE_SEND;
break;
case SHUT_RDWR:
wasi_how = TCP_SHUTDOWN_TYPE_BOTH;
break;
default:
errno = EINVAL;
return -1;
}

tcp_socket_state_connected_t connection;
if (socket->state.tag == TCP_SOCKET_STATE_CONNECTED) {
connection = socket->state.connected;
} else {
errno = ENOTCONN;
return -1;
}

network_error_code_t error;
tcp_borrow_tcp_socket_t socket_borrow =
tcp_borrow_tcp_socket(socket->socket);
if (!tcp_method_tcp_socket_shutdown(socket_borrow, wasi_how, &error)) {
errno = __wasi_sockets_utils__map_error(error);
return -1;
}

if (posix_how == SHUT_RD || posix_how == SHUT_RDWR) {
// TODO wasi-sockets: drop input stream (if not already). And
// update `recv` to take dropped input streams into account.
}

if (posix_how == SHUT_WR || posix_how == SHUT_RDWR) {
// TODO wasi-sockets: drop output stream (if not already). And
// update `send` to take dropped output streams into account.
}

return 0;
}

int udp_shutdown(udp_socket_t *socket, int posix_how)
{
// UDP has nothing to shut down.
errno = EOPNOTSUPP;
return -1;
}

int shutdown(int socket, int how)
{
descriptor_table_entry_t *entry;
if (!descriptor_table_get_ref(socket, &entry)) {
errno = EBADF;
return -1;
}

switch (entry->tag) {
case DESCRIPTOR_TABLE_ENTRY_TCP_SOCKET:
return tcp_shutdown(&entry->tcp_socket, how);
case DESCRIPTOR_TABLE_ENTRY_UDP_SOCKET:
return udp_shutdown(&entry->udp_socket, how);
default:
errno = EOPNOTSUPP;
return -1;
}
}
Loading

0 comments on commit 7204dc0

Please sign in to comment.