summaryrefslogtreecommitdiff
path: root/shared/net_compat.h
diff options
context:
space:
mode:
Diffstat (limited to 'shared/net_compat.h')
-rw-r--r--shared/net_compat.h61
1 files changed, 61 insertions, 0 deletions
diff --git a/shared/net_compat.h b/shared/net_compat.h
new file mode 100644
index 0000000..5e63e04
--- /dev/null
+++ b/shared/net_compat.h
@@ -0,0 +1,61 @@
+// net_compat.h
+#pragma once
+
+#ifdef _WIN32
+ #include <winsock2.h>
+ #include <ws2tcpip.h>
+ #pragma comment(lib, "ws2_32.lib")
+
+ // Map POSIX names to Winsock equivalents
+ #define close(s) closesocket(s)
+ #define MSG_DONTWAIT 0 // no direct equivalent, use non-blocking mode instead
+
+ static inline int net_errno(void) { return WSAGetLastError(); }
+ #define NET_EAGAIN WSAEWOULDBLOCK
+ #define NET_EINTR WSAEINTR
+
+ typedef int socklen_t;
+
+ // err.h doesn't exist on Windows — provide a minimal shim
+ #include <stdio.h>
+ #include <stdlib.h>
+ static inline void err(int code, const char *msg) {
+ fprintf(stderr, "%s: WSA error %d\n", msg, WSAGetLastError());
+ exit(code);
+ }
+
+ // Winsock requires explicit init/cleanup
+ static inline void net_init(void) {
+ WSADATA wsa;
+ if (WSAStartup(MAKEWORD(2,2), &wsa) != 0) {
+ fprintf(stderr, "WSAStartup failed\n");
+ exit(EXIT_FAILURE);
+ }
+ }
+ static inline void net_cleanup(void) { WSACleanup(); }
+
+ // Non-blocking: Winsock uses ioctlsocket instead of MSG_DONTWAIT
+ #include <winsock2.h>
+ static inline void set_nonblocking(SOCKET s) {
+ u_long mode = 1;
+ ioctlsocket(s, FIONBIO, &mode);
+ }
+
+#else
+ #include <sys/socket.h>
+ #include <netinet/in.h>
+ #include <unistd.h>
+ #include <err.h>
+ #include <errno.h>
+ #include <fcntl.h>
+
+ static inline void net_init(void) {} // no-op on POSIX
+ static inline void net_cleanup(void) {} // no-op on POSIX
+ static inline void set_nonblocking(int s) {
+ fcntl(s, F_SETFL, fcntl(s, F_GETFL) | O_NONBLOCK);
+ }
+
+ static inline int net_errno(void) { return errno; }
+ #define NET_EAGAIN EAGAIN
+ #define NET_EINTR EINTR
+#endif