From 1d1c9f36f43314523187b8e1fb868d03718dcc79 Mon Sep 17 00:00:00 2001 From: Romain Vimont Date: Thu, 9 Sep 2021 18:07:38 +0200 Subject: [PATCH] Retrieve correct error messages on Windows For sockets functions, Windows does not store error codes in errno, so perror() does not print any error. Use WSAGetLastError() instead. Refs #2624 --- app/src/util/net.c | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/app/src/util/net.c b/app/src/util/net.c index 75daef8b..17299424 100644 --- a/app/src/util/net.c +++ b/app/src/util/net.c @@ -19,11 +19,27 @@ typedef struct in_addr IN_ADDR; #endif +static void +net_perror(const char *s) { +#ifdef _WIN32 + int error = WSAGetLastError(); + char *wsa_message; + FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, + NULL, error, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + (char *) &wsa_message, 0, NULL); + // no explicit '\n', wsa_message already contains a trailing '\n' + fprintf(stderr, "%s: [%d] %s", s, error, wsa_message); + LocalFree(wsa_message); +#else + perror(s); +#endif +} + socket_t net_connect(uint32_t addr, uint16_t port) { socket_t sock = socket(AF_INET, SOCK_STREAM, 0); if (sock == INVALID_SOCKET) { - perror("socket"); + net_perror("socket"); return INVALID_SOCKET; } @@ -33,7 +49,7 @@ net_connect(uint32_t addr, uint16_t port) { sin.sin_port = htons(port); if (connect(sock, (SOCKADDR *) &sin, sizeof(sin)) == SOCKET_ERROR) { - perror("connect"); + net_perror("connect"); net_close(sock); return INVALID_SOCKET; } @@ -45,14 +61,14 @@ socket_t net_listen(uint32_t addr, uint16_t port, int backlog) { socket_t sock = socket(AF_INET, SOCK_STREAM, 0); if (sock == INVALID_SOCKET) { - perror("socket"); + net_perror("socket"); return INVALID_SOCKET; } int reuse = 1; if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (const void *) &reuse, sizeof(reuse)) == -1) { - perror("setsockopt(SO_REUSEADDR)"); + net_perror("setsockopt(SO_REUSEADDR)"); } SOCKADDR_IN sin; @@ -61,13 +77,13 @@ net_listen(uint32_t addr, uint16_t port, int backlog) { sin.sin_port = htons(port); if (bind(sock, (SOCKADDR *) &sin, sizeof(sin)) == SOCKET_ERROR) { - perror("bind"); + net_perror("bind"); net_close(sock); return INVALID_SOCKET; } if (listen(sock, backlog) == SOCKET_ERROR) { - perror("listen"); + net_perror("listen"); net_close(sock); return INVALID_SOCKET; }