master
1#include <wasi/api.h>
2#include <wasi/libc.h>
3#include <errno.h>
4#include <unistd.h>
5
6int __wasilibc_fd_renumber(int fd, int newfd) {
7 // Scan the preopen fds before making any changes.
8 __wasilibc_populate_preopens();
9
10 __wasi_errno_t error = __wasi_fd_renumber(fd, newfd);
11 if (error != 0) {
12 errno = error;
13 return -1;
14 }
15 return 0;
16}
17
18#ifdef __wasilibc_use_wasip2
19#include <wasi/descriptor_table.h>
20
21void drop_tcp_socket(tcp_socket_t socket) {
22 switch (socket.state.tag) {
23 case TCP_SOCKET_STATE_UNBOUND:
24 case TCP_SOCKET_STATE_BOUND:
25 case TCP_SOCKET_STATE_CONNECTING:
26 case TCP_SOCKET_STATE_LISTENING:
27 case TCP_SOCKET_STATE_CONNECT_FAILED:
28 // No additional resources to drop.
29 break;
30 case TCP_SOCKET_STATE_CONNECTED: {
31 tcp_socket_state_connected_t connection = socket.state.connected;
32
33 poll_pollable_drop_own(connection.input_pollable);
34 poll_pollable_drop_own(connection.output_pollable);
35 streams_input_stream_drop_own(connection.input);
36 streams_output_stream_drop_own(connection.output);
37 break;
38 }
39 default: /* unreachable */ abort();
40 }
41
42 poll_pollable_drop_own(socket.socket_pollable);
43 tcp_tcp_socket_drop_own(socket.socket);
44}
45
46void drop_udp_socket_streams(udp_socket_streams_t streams) {
47 poll_pollable_drop_own(streams.incoming_pollable);
48 poll_pollable_drop_own(streams.outgoing_pollable);
49 udp_incoming_datagram_stream_drop_own(streams.incoming);
50 udp_outgoing_datagram_stream_drop_own(streams.outgoing);
51}
52
53void drop_udp_socket(udp_socket_t socket) {
54 switch (socket.state.tag) {
55 case UDP_SOCKET_STATE_UNBOUND:
56 case UDP_SOCKET_STATE_BOUND_NOSTREAMS:
57 // No additional resources to drop.
58 break;
59 case UDP_SOCKET_STATE_BOUND_STREAMING:
60 drop_udp_socket_streams(socket.state.bound_streaming.streams);
61 break;
62 case UDP_SOCKET_STATE_CONNECTED: {
63 drop_udp_socket_streams(socket.state.connected.streams);
64 break;
65 }
66 default: /* unreachable */ abort();
67 }
68
69 poll_pollable_drop_own(socket.socket_pollable);
70 udp_udp_socket_drop_own(socket.socket);
71}
72#endif // __wasilibc_use_wasip2
73
74int close(int fd) {
75 // Scan the preopen fds before making any changes.
76 __wasilibc_populate_preopens();
77
78#ifdef __wasilibc_use_wasip2
79 descriptor_table_entry_t entry;
80 if (descriptor_table_remove(fd, &entry)) {
81
82 switch (entry.tag)
83 {
84 case DESCRIPTOR_TABLE_ENTRY_TCP_SOCKET:
85 drop_tcp_socket(entry.tcp_socket);
86 break;
87 case DESCRIPTOR_TABLE_ENTRY_UDP_SOCKET:
88 drop_udp_socket(entry.udp_socket);
89 break;
90 default: /* unreachable */ abort();
91 }
92
93 return 0;
94 }
95#endif // __wasilibc_use_wasip2
96
97 __wasi_errno_t error = __wasi_fd_close(fd);
98 if (error != 0) {
99 errno = error;
100 return -1;
101 }
102
103 return 0;
104}
105
106weak void __wasilibc_populate_preopens(void) {
107 // This version does nothing. It may be overridden by a version which does
108 // something if `__wasilibc_find_abspath` or `__wasilibc_find_relpath` are
109 // used.
110}