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}