From 8734c6a57f9c790c405e505b1d14783d13710606 Mon Sep 17 00:00:00 2001 From: Larry Frieson Date: Thu, 14 Dec 2023 22:40:43 -0800 Subject: [PATCH] Return actual socket errors on Windows. --- exec/cnex/lib/net.c | 24 ++++++++++++++++++++---- lib/net.cpp | 28 +++++++++++++++++++++++----- src/socketx.h | 2 ++ 3 files changed, 45 insertions(+), 9 deletions(-) diff --git a/exec/cnex/lib/net.c b/exec/cnex/lib/net.c index 38205be325..7a23ab61ba 100644 --- a/exec/cnex/lib/net.c +++ b/exec/cnex/lib/net.c @@ -250,9 +250,15 @@ void net_socket_recv(TExecutor *exec) fatal_error("Could not allocate %d bytes for socket_recv().", n); } int r = recv(s, (char*)buf, n, 0); + if (r == SOCKET_ERROR) { + if (WSAGetLastError() == WSAEWOULDBLOCK) { + assert("Socket would block!"); + } + } if (r < 0) { + perror("recv"); - int err = errno; + int err = WSAGetLastError(); Cell *ret = cell_createArrayCell(2); Cell *t = cell_arrayIndexForWrite(ret, 0); t->type = cNumber; @@ -308,6 +314,11 @@ void net_socket_select(TExecutor *exec) Cell *write = peek(exec->stack, 1)->address; Cell *read = peek(exec->stack, 2)->address; + //Cell *error = top(exec->stack)->address; pop(exec->stack); + //Cell *write = top(exec->stack)->address; pop(exec->stack); + //Cell *read = top(exec->stack)->address; pop(exec->stack); + + fd_set rfds, wfds, efds; FD_ZERO(&rfds); FD_ZERO(&wfds); @@ -375,6 +386,9 @@ void net_socket_select(TExecutor *exec) array_clearArray(read->array); array_clearArray(write->array); array_clearArray(error->array); + pop(exec->stack); + pop(exec->stack); + pop(exec->stack); push(exec->stack, cell_fromBoolean(FALSE)); return; } @@ -392,7 +406,7 @@ void net_socket_select(TExecutor *exec) for (size_t i = 0; i < write->array->size; ) { SOCKET *ps = check_socket(exec, write->array->data[i].array->data[0].object); SOCKET fd = *ps; - if (FD_ISSET(fd, &rfds)) { + if (FD_ISSET(fd, &wfds)) { ++i; } else { array_removeItem(write->array, i); @@ -402,12 +416,14 @@ void net_socket_select(TExecutor *exec) for (size_t i = 0; i < error->array->size; ) { SOCKET *ps = check_socket(exec, error->array->data[i].array->data[0].object); SOCKET fd = *ps; - if (FD_ISSET(fd, &rfds)) { + if (FD_ISSET(fd, &efds)) { ++i; } else { array_removeItem(error->array, i); } } - + //pop(exec->stack); + //pop(exec->stack); + //pop(exec->stack); push(exec->stack, cell_fromBoolean(TRUE)); } diff --git a/lib/net.cpp b/lib/net.cpp index beacfcb7b8..3f72dec7f5 100644 --- a/lib/net.cpp +++ b/lib/net.cpp @@ -15,6 +15,26 @@ // https://wiki.openssl.org/index.php/SSL/TLS_Client +static std::string socket_error(int err) +{ + static char msgbuf[256] = { '\0' }; +#ifdef _WIN32 + FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, + err, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + msgbuf, + sizeof(msgbuf), + NULL); +#else + snprintf(msgbuf, sizeof(msgbuf), "%s", strerror(err)); +#endif + if (msgbuf[0] == '\0') { + snprintf(msgbuf, sizeof(msgbuf), "(No Error Text) - %d", err); + } + return std::string(msgbuf); +} + class SocketObject: public Object { public: SocketObject() {} @@ -133,9 +153,8 @@ class RawSocketObject: public SocketObject { std::vector buffer(n); int r = ::recv(handle, reinterpret_cast(const_cast(buffer.data())), n, 0); if (r < 0) { - int err = errno; - perror("recv"); - return Cell(std::vector {Cell(number_from_uint32(CHOICE_RecvResult_error)), Cell(utf8string(strerror(err)))}); + int err = socketerror; + return Cell(std::vector {Cell(number_from_uint32(CHOICE_RecvResult_error)), Cell(utf8string(socket_error(err)))}); } if (r == 0) { return Cell(std::vector {Cell(number_from_uint32(CHOICE_RecvResult_eof))}); @@ -150,8 +169,7 @@ class RawSocketObject: public SocketObject { socklen_t sin_len = sizeof(sin); int r = ::recvfrom(handle, reinterpret_cast(const_cast(buffer.data())), n, 0, reinterpret_cast(&sin), &sin_len); if (r < 0) { - int err = errno; - perror("recvfrom"); + int err = socketerror; return Cell(std::vector {Cell(number_from_uint32(CHOICE_RecvFromResult_error)), Cell(utf8string(strerror(err)))}); } if (r == 0) { diff --git a/src/socketx.h b/src/socketx.h index eece91497b..f3ae556c26 100644 --- a/src/socketx.h +++ b/src/socketx.h @@ -3,6 +3,7 @@ #include typedef int socklen_t; #pragma warning(disable: 4127) // incompatible with FD_SET() +#define socketerror WSAGetLastError() #else @@ -15,5 +16,6 @@ typedef int socklen_t; typedef int SOCKET; const int INVALID_SOCKET = -1; inline void closesocket(int x) { close(x); } +#define socketerror errno #endif