diff --git a/libc/calls/ioctl.c b/libc/calls/ioctl.c index 1130a6c34..5151c8524 100644 --- a/libc/calls/ioctl.c +++ b/libc/calls/ioctl.c @@ -38,6 +38,7 @@ #include "libc/nt/iphlpapi.h" #include "libc/nt/runtime.h" #include "libc/nt/struct/ipadapteraddresses.h" +#include "libc/nt/thunk/msabi.h" #include "libc/nt/winsock.h" #include "libc/runtime/runtime.h" #include "libc/runtime/stack.h" @@ -59,6 +60,8 @@ #define MAX_UNICAST_ADDR 32 #define MAX_NAME_CLASH ((int)('z' - 'a')) /* Allow a..z */ +__msabi extern typeof(__sys_ioctlsocket_nt) *const __imp_ioctlsocket; + static struct HostAdapterInfoNode { struct HostAdapterInfoNode *next; char name[IFNAMSIZ]; /* Obtained from FriendlyName */ @@ -76,7 +79,7 @@ static int ioctl_default(int fd, unsigned long request, void *arg) { } else if (__isfdopen(fd)) { if (g_fds.p[fd].kind == kFdSocket) { handle = g_fds.p[fd].handle; - if ((rc = _weaken(__sys_ioctlsocket_nt)(handle, request, arg)) != -1) { + if ((rc = __imp_ioctlsocket(handle, request, arg)) != -1) { return rc; } else { return _weaken(__winsockerr)(); @@ -97,7 +100,7 @@ static int ioctl_fionread(int fd, uint32_t *arg) { } else if (__isfdopen(fd)) { handle = g_fds.p[fd].handle; if (g_fds.p[fd].kind == kFdSocket) { - if ((rc = _weaken(__sys_ioctlsocket_nt)(handle, FIONREAD, arg)) != -1) { + if ((rc = __imp_ioctlsocket(handle, FIONREAD, arg)) != -1) { return rc; } else { return _weaken(__winsockerr)(); diff --git a/libc/sock/recv-nt.c b/libc/sock/recv-nt.c index 5457a335d..14b0e0edd 100644 --- a/libc/sock/recv-nt.c +++ b/libc/sock/recv-nt.c @@ -39,7 +39,7 @@ struct RecvArgs { struct NtIovec iovnt[16]; }; -static textwindows int sys_recv_nt_start(int64_t handle, +textwindows static int sys_recv_nt_start(int64_t handle, struct NtOverlapped *overlap, uint32_t *flags, void *arg) { struct RecvArgs *args = arg; diff --git a/libc/sock/recvfrom-nt.c b/libc/sock/recvfrom-nt.c index d1f6f5572..c94c94260 100644 --- a/libc/sock/recvfrom-nt.c +++ b/libc/sock/recvfrom-nt.c @@ -42,7 +42,7 @@ struct RecvFromArgs { struct NtIovec iovnt[16]; }; -static textwindows int sys_recvfrom_nt_start(int64_t handle, +textwindows static int sys_recvfrom_nt_start(int64_t handle, struct NtOverlapped *overlap, uint32_t *flags, void *arg) { struct RecvFromArgs *args = arg; diff --git a/libc/sock/send-nt.c b/libc/sock/send-nt.c index bccb7cdc7..63802586f 100644 --- a/libc/sock/send-nt.c +++ b/libc/sock/send-nt.c @@ -38,7 +38,7 @@ struct SendArgs { struct NtIovec iovnt[16]; }; -static textwindows int sys_send_nt_start(int64_t handle, +textwindows static int sys_send_nt_start(int64_t handle, struct NtOverlapped *overlap, uint32_t *flags, void *arg) { struct SendArgs *args = arg; diff --git a/libc/sysv/consts.sh b/libc/sysv/consts.sh index 41dec4c43..156699952 100755 --- a/libc/sysv/consts.sh +++ b/libc/sysv/consts.sh @@ -19,10 +19,6 @@ dir=libc/sysv/consts . libc/sysv/gen.sh -# syscon errno EALREADY 114 114 37 37 37 37 37 10037 # connection already in progress; bsd consensus; WSAEALREADY; raised by connect(2), send(2), ip(7) -# syscon errno EINPROGRESS 115 115 36 36 36 36 36 10036 # bsd consensus; WSAEINPROGRESS; raised by connect(2) w/ O_NONBLOCK -# syscon errno EISCONN 106 106 56 56 56 56 56 10056 # socket is connected; bsd consensus; WSAEISCONN; raised by connect(2), send(2), unix(7), ip(7) - # The Fifth Bell System, Community Edition # ยป catalogue of carnage # diff --git a/test/posix/socket_fionread_test.c b/test/posix/socket_fionread_test.c new file mode 100644 index 000000000..c6fd81413 --- /dev/null +++ b/test/posix/socket_fionread_test.c @@ -0,0 +1,69 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +int main() { + + // create server socket + int server_fd; + struct sockaddr_in address; + int addrlen = sizeof(address); + if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == -1) + return 1; + address.sin_family = AF_INET; + address.sin_addr.s_addr = htonl(INADDR_LOOPBACK); + address.sin_port = 0; // let os assign random port + if (bind(server_fd, (struct sockaddr *)&address, sizeof(address))) + return 2; + if (getsockname(server_fd, (struct sockaddr *)&address, + (socklen_t *)&addrlen)) + return 3; + if (listen(server_fd, SOMAXCONN)) + return 4; + + // create client socket + int client_fd; + if ((client_fd = socket(AF_INET, SOCK_STREAM, 0)) == -1) + return 6; + if (connect(client_fd, (struct sockaddr *)&address, sizeof(address))) + return 7; + + // accept client and send data + int server_client_fd; + if ((server_client_fd = accept(server_fd, 0, 0)) == -1) + return 8; + if (write(server_client_fd, "hi", 2) != 2) + return 9; + + // poll to be safe (important for mac/bsd) + struct pollfd fds[] = {{client_fd, POLLIN}}; + if (poll(fds, 1, -1u) != 1) + return 10; + + // ask how many bytes we can read + uint32_t bytes_available; + if (ioctl(client_fd, FIONREAD, &bytes_available)) + return 11; + if (bytes_available != 2) { + printf("wut %d\n", bytes_available); + return 12; + } + + // clean up + if (close(client_fd)) + return 13; + if (close(server_fd)) + return 14; + + CheckForMemoryLeaks(); +}