You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

143 lines
3.9 KiB

/**
* Platform compatibility layer for POSIX functions on Windows
*/
#ifndef PLATFORM_COMPAT_H
#define PLATFORM_COMPAT_H
#ifdef _WIN32
#include <winsock2.h>
#include <ws2tcpip.h>
#include <windows.h>
#include <io.h>
#include <time.h>
#include <fcntl.h>
#include <stdint.h>
// POSIX functions missing on Windows
#define strcasecmp _stricmp
#define strncasecmp _strnicmp
// poll() and pollfd are already defined in winsock2.h on MSYS2 UCRT64
// Only define if not already present
#ifndef POLLIN
#define POLLIN 0x0001
#endif
#ifndef POLLOUT
#define POLLOUT 0x0004
#endif
#ifndef POLLERR
#define POLLERR 0x0008
#endif
#ifndef POLLHUP
#define POLLHUP 0x0010
#endif
#ifndef POLLNVAL
#define POLLNVAL 0x0020
#endif
#ifndef POLLPRI
#define POLLPRI 0x0002
#endif
// ssize_t for Windows (signed size type)
#ifndef _SSIZE_T_DEFINED
typedef long ssize_t;
#define _SSIZE_T_DEFINED
#endif
// gettimeofday for Windows - provide our own implementation if not already defined
#ifndef _GETTIMEOFDAY_DEFINED
#define _GETTIMEOFDAY_DEFINED
static inline int utun_gettimeofday(struct timeval *tv, void *tz) {
FILETIME ft;
unsigned __int64 tmpres = 0;
if (tv != NULL) {
GetSystemTimeAsFileTime(&ft);
tmpres |= ft.dwHighDateTime;
tmpres <<= 32;
tmpres |= ft.dwLowDateTime;
// Convert from 100-nanosecond intervals to microseconds
tmpres /= 10;
// Convert to Unix epoch (January 1, 1970)
tmpres -= 11644473600000000ULL;
tv->tv_sec = (long)(tmpres / 1000000UL);
tv->tv_usec = (long)(tmpres % 1000000UL);
}
// tz parameter is ignored (for compatibility with POSIX)
return 0;
}
#endif // _GETTIMEOFDAY_DEFINED
// Pipe creation for Windows
static inline int platform_pipe(int pipefd[2]) {
return _pipe(pipefd, 4096, _O_BINARY);
}
#define pipe platform_pipe
// nfds_t already defined in winsock2.h on MSYS2
// fcntl replacement for Windows (simplified - only supports F_GETFL/F_SETFL with O_NONBLOCK)
#ifndef F_GETFL
#define F_GETFL 3
#endif
#ifndef F_SETFL
#define F_SETFL 4
#endif
#ifndef O_NONBLOCK
#define O_NONBLOCK 0x4000
#endif
static inline int platform_fcntl(int fd, int cmd, ... /* arg */ ) {
va_list ap;
va_start(ap, cmd);
if (cmd == F_GETFL) {
va_end(ap);
// Return current flags (always 0 on Windows, can't query easily)
return 0;
} else if (cmd == F_SETFL) {
int flags = va_arg(ap, int);
va_end(ap);
if (flags & O_NONBLOCK) {
// Set non-blocking mode
u_long mode = 1;
return ioctlsocket(fd, FIONBIO, &mode);
}
return 0;
}
va_end(ap);
errno = EINVAL;
return -1;
}
#define fcntl platform_fcntl
// nanosleep already defined in pthread_time.h on MSYS2
// poll() and pollfd already defined in winsock2.h on MSYS2
// Use WSAPoll on Windows (available in Vista and later)
#define poll WSAPoll
// sa_family_t might not be defined on some Windows setups
#ifndef sa_family_t
typedef unsigned short sa_family_t;
#endif
#else
// POSIX - include standard headers
#include <sys/time.h>
#include <strings.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <fcntl.h>
#include <unistd.h>
#include <poll.h>
#endif
// Generate cryptographically secure random bytes
// Returns 0 on success, -1 on error
int random_bytes(uint8_t *buffer, size_t len);
#endif // PLATFORM_COMPAT_H