diff options
Diffstat (limited to 'src/libstrongswan/utils/compat/windows.h')
-rw-r--r-- | src/libstrongswan/utils/compat/windows.h | 627 |
1 files changed, 627 insertions, 0 deletions
diff --git a/src/libstrongswan/utils/compat/windows.h b/src/libstrongswan/utils/compat/windows.h new file mode 100644 index 000000000..fd4f1f196 --- /dev/null +++ b/src/libstrongswan/utils/compat/windows.h @@ -0,0 +1,627 @@ +/* + * Copyright (C) 2013 Martin Willi + * Copyright (C) 2013 revosec AG + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + */ + +/** + * @defgroup windows windows + * @{ @ingroup compat + */ + +#ifndef WINDOWS_H_ +#define WINDOWS_H_ + +#include <winsock2.h> +#include <ws2tcpip.h> +#include <direct.h> +#include <inttypes.h> +#include <unistd.h> +#include <sys/stat.h> + +/* undef Windows variants evaluating values more than once */ +#undef min +#undef max + +/* interface is defined as an alias to "struct" in basetypes.h, but + * we use it here and there as ordinary identifier. */ +#undef interface + +/* used by Windows API, but we have our own */ +#undef CALLBACK + +/* UID/GID types for capabilities, even if not supported */ +typedef u_int uid_t; +typedef u_int gid_t; + +/** + * Initialize Windows libraries + */ +void windows_init(); + +/** + * Deinitialize windows libraries + */ +void windows_deinit(); + +/** + * Replacement for random(3) + */ +static inline long random(void) +{ + return rand(); +} + +/** + * Replacement for srandom(3) + */ +static inline void srandom(unsigned int seed) +{ + srand(seed); +} + +/** + * Replacement of sched_yield(2) from <sched.h> + */ +static inline int sched_yield(void) +{ + Sleep(0); + return 0; +} + +/** + * Replacement of sleep(3), cancellable by thread_cancel() + */ +#define sleep sleep_cancellable +static inline int sleep_cancellable(unsigned int seconds) +{ + SleepEx(seconds * 1000, TRUE); + return 0; +} + +/** + * Replacement of usleep(3), cancellable, ms resolution only + */ +int usleep(useconds_t usec); + +/** + * strdup(3), the Windows variant can't free(strdup("")) and others + */ +#define strdup strdup_windows +static inline char* strdup_windows(const char *src) +{ + size_t len; + char *dst; + + len = strlen(src) + 1; + dst = malloc(len); + memcpy(dst, src, len); + return dst; +} + +/** + * strndup(3) + */ +char* strndup(const char *s, size_t n); + +/** + * Provided via ws2_32 + */ +#ifndef InetNtop +const char WINAPI *inet_ntop(int af, const void *src, char *dst, socklen_t size); +#endif + +/** + * Provided via ws2_32 + */ +#ifndef InetPton +int WINAPI inet_pton(int af, const char *src, void *dst); +#endif + +/** + * Provided by printf hook backend + */ +int asprintf(char **strp, const char *fmt, ...); + +/** + * Provided by printf hook backend + */ +int vasprintf(char **strp, const char *fmt, va_list ap); + +/** + * timeradd(3) from <sys/time.h> + */ +static inline void timeradd(struct timeval *a, struct timeval *b, + struct timeval *res) +{ + res->tv_sec = a->tv_sec + b->tv_sec; + res->tv_usec = a->tv_usec + b->tv_usec; + if (res->tv_usec >= 1000000) + { + res->tv_usec -= 1000000; + res->tv_sec++; + } +} + +/** + * timersub(3) from <sys/time.h> + */ +static inline void timersub(struct timeval *a, struct timeval *b, + struct timeval *res) +{ + res->tv_sec = a->tv_sec - b->tv_sec; + res->tv_usec = a->tv_usec - b->tv_usec; + if (res->tv_usec < 0) + { + res->tv_usec += 1000000; + res->tv_sec--; + } +} + +/** + * gmtime_r(3) from <time.h> + */ +static inline struct tm *gmtime_r(const time_t *timep, struct tm *result) +{ + struct tm *ret; + + /* gmtime_s() and friends seem not to be implemented/functioning. + * Relying on gmtime() on Windows works as well, as it uses thread + * specific buffers. */ + ret = gmtime(timep); + if (ret) + { + memcpy(result, ret, sizeof(*result)); + } + return ret; +} + +/** + * localtime_r(3) from <time.h> + */ +static inline struct tm *localtime_r(const time_t *timep, struct tm *result) +{ + struct tm *ret; + + /* localtime_s() and friends seem not to be implemented/functioning. + * Relying on localtime() on Windows works as well, as it uses thread + * specific buffers. */ + ret = localtime(timep); + if (ret) + { + memcpy(result, ret, sizeof(*result)); + } + return ret; +} + +/** + * setenv(3) from <stdlib.h>, overwrite flag is ignored + */ +static inline int setenv(const char *name, const char *value, int overwrite) +{ + if (SetEnvironmentVariableA(name, value) == 0) + { /* failed */ + return -1; + } + return 0; +} + +/** + * Lazy binding, ignored on Windows + */ +#define RTLD_LAZY 1 + +/** + * Default handle targeting .exe + */ +#define RTLD_DEFAULT (NULL) + +/** + * Find symbol in next library + */ +#define RTLD_NEXT ((void*)~(uintptr_t)0) + +/** + * dlopen(3) from <dlfcn.h> + */ +void* dlopen(const char *filename, int flag); + +/** + * dlsym() from <dlfcn.h> + */ +void* dlsym(void *handle, const char *symbol); + +/** + * dlerror(3) from <dlfcn.h>, currently not thread save + */ +char* dlerror(void); + +/** + * dlclose() from <dlfcn.h> + */ +int dlclose(void *handle); + +/** + * socketpair(2) for SOCK_STREAM, uses TCP on loopback + */ +int socketpair(int domain, int type, int protocol, int sv[2]); + +/** + * getpass(3) on Windows consoles + */ +char* getpass(const char *prompt); +#define HAVE_GETPASS + +/** + * Map MSG_DONTWAIT to the reserved, but deprecated MSG_INTERRUPT + */ +#define MSG_DONTWAIT MSG_INTERRUPT + +/** + * shutdown(2) "how"-aliases, to use Unix variant on Windows + */ +#define SHUT_RD SD_RECEIVE +#define SHUT_WR SD_SEND +#define SHUT_RDWR SD_BOTH + +/** + * shutdown(2) setting errno + */ +#define shutdown windows_shutdown +int windows_shutdown(int sockfd, int how); + +/** + * accept(2) setting errno + */ +#define accept windows_accept +int windows_accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen); + +/** + * bind(2) setting errno + */ +#define bind windows_bind +int windows_bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen); + +/** + * connect(2) setting errno + */ +#define connect windows_connect +int windows_connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen); + +/** + * getsockname(2) setting errno + */ +#define getsockname windows_getsockname +int windows_getsockname(int sockfd, struct sockaddr *addr, socklen_t *addrlen); + +/** + * getsockopt(2) setting errno + */ +#define getsockopt windows_getsockopt +int windows_getsockopt(int sockfd, int level, int optname, + void *optval, socklen_t *optlen); + +/** + * setsockopt(2) setting errno + */ +#define setsockopt windows_setsockopt +int windows_setsockopt(int sockfd, int level, int optname, + const void *optval, socklen_t optlen); + +/** + * socket(2) setting errno + */ +#define socket windows_socket +int windows_socket(int domain, int type, int protocol); + +/** + * select(2) setting errno + */ +#define select windows_select +int windows_select(int nfds, fd_set *readfds, fd_set *writefds, + fd_set *exceptfds, struct timeval *timeout); + +/** + * close(2) working for file handles and Winsock sockets + */ +#define close windows_close +int windows_close(int fd); + +/** + * recv(2) with support for MSG_DONTWAIT + */ +#define recv windows_recv +ssize_t windows_recv(int sockfd, void *buf, size_t len, int flags); + +/** + * recvfrom(2) with support for MSG_DONTWAIT + */ +#define recvfrom windows_recvfrom +ssize_t windows_recvfrom(int sockfd, void *buf, size_t len, int flags, + struct sockaddr *src_addr, socklen_t *addrlen); + +/** + * recvfrom(2) with support for MSG_DONTWAIT + */ +#define send windows_send +ssize_t windows_send(int sockfd, const void *buf, size_t len, int flags); + +/** + * recvfrom(2) with support for MSG_DONTWAIT + */ +#define sendto windows_send +ssize_t windows_sendto(int sockfd, const void *buf, size_t len, int flags, + const struct sockaddr *dest_addr, socklen_t addrlen); + +/** + * read(2) working on files and sockets, cancellable on sockets only + * + * On Windows, there does not seem to be a way how a cancellable read can + * be implemented on Low level I/O functions for files, _pipe()s or stdio. + */ +#define read windows_read +ssize_t windows_read(int fd, void *buf, size_t count); + +/** + * write(2) working on files and sockets + */ +#define write windows_write +ssize_t windows_write(int fd, void *buf, size_t count); + +#if _WIN32_WINNT < 0x0600 +/** + * Define pollfd and flags on our own if not specified + */ +struct pollfd { + SOCKET fd; + short events; + short revents; +}; +enum { + POLLERR = 0x0001, + POLLHUP = 0x0002, + POLLNVAL = 0x0004, + POLLWRNORM = 0x0010, + POLLWRBAND = 0x0020, + POLLPRI = 0x0400, + POLLRDNORM = 0x0100, + POLLRDBAND = 0x0200, + POLLIN = POLLRDNORM | POLLRDBAND, + POLLOUT = POLLWRNORM, +}; +#endif /* _WIN32_WINNT < 0x0600 */ + +/** + * poll(2), implemented using Winsock2 WSAPoll() + */ +int poll(struct pollfd *fds, int nfds, int timeout); + +/** + * Declaration missing on older WinGW + */ +_CRTIMP errno_t strerror_s(char *buf, size_t size, int errnum); + +/** + * strerror_s, but supporting POSIX compatibility errno >= 100 + */ +#define strerror_s strerror_s_extended +int strerror_s_extended(char *buf, size_t buflen, int errnum); + +/** + * strerror_r(2) replacement, XSI variant + */ +static inline int strerror_r(int errnum, char *buf, size_t buflen) +{ + return strerror_s(buf, buflen, errnum); +} +#define HAVE_STRERROR_R /* but not STRERROR_R_CHAR_P */ + +/** + * MinGW does provide extended errno values. Windows itself knowns them + * for POSIX compatibility; we define them as well. + */ +#ifndef EADDRINUSE +#define EADDRINUSE 100 +#endif +#ifndef EADDRNOTAVAIL +#define EADDRNOTAVAIL 101 +#endif +#ifndef EAFNOSUPPORT +#define EAFNOSUPPORT 102 +#endif +#ifndef EALREADY +#define EALREADY 103 +#endif +#ifndef EBADMSG +#define EBADMSG 104 +#endif +#ifndef ECANCELED +#define ECANCELED 105 +#endif +#ifndef ECONNABORTED +#define ECONNABORTED 106 +#endif +#ifndef ECONNREFUSED +#define ECONNREFUSED 107 +#endif +#ifndef ECONNRESET +#define ECONNRESET 108 +#endif +#ifndef EDESTADDRREQ +#define EDESTADDRREQ 109 +#endif +#ifndef EHOSTUNREACH +#define EHOSTUNREACH 110 +#endif +#ifndef EIDRM +#define EIDRM 111 +#endif +#ifndef EINPROGRESS +#define EINPROGRESS 112 +#endif +#ifndef EISCONN +#define EISCONN 113 +#endif +#ifndef ELOOP +#define ELOOP 114 +#endif +#ifndef EMSGSIZE +#define EMSGSIZE 115 +#endif +#ifndef ENETDOWN +#define ENETDOWN 116 +#endif +#ifndef ENETRESET +#define ENETRESET 117 +#endif +#ifndef ENETUNREACH +#define ENETUNREACH 118 +#endif +#ifndef ENOBUFS +#define ENOBUFS 119 +#endif +#ifndef ENODATA +#define ENODATA 120 +#endif +#ifndef ENOLINK +#define ENOLINK 121 +#endif +#ifndef ENOMSG +#define ENOMSG 122 +#endif +#ifndef ENOPROTOOPT +#define ENOPROTOOPT 123 +#endif +#ifndef ENOSR +#define ENOSR 124 +#endif +#ifndef ENOSTR +#define ENOSTR 125 +#endif +#ifndef ENOTCONN +#define ENOTCONN 126 +#endif +#ifndef ENOTRECOVERABLE +#define ENOTRECOVERABLE 127 +#endif +#ifndef ENOTSOCK +#define ENOTSOCK 128 +#endif +#ifndef ENOTSUP +#define ENOTSUP 129 +#endif +#ifndef EOPNOTSUPP +#define EOPNOTSUPP 130 +#endif +#ifndef EOTHER +#define EOTHER 131 +#endif +#ifndef EOVERFLOW +#define EOVERFLOW 132 +#endif +#ifndef EOWNERDEAD +#define EOWNERDEAD 133 +#endif +#ifndef EPROTO +#define EPROTO 134 +#endif +#ifndef EPROTONOSUPPORT +#define EPROTONOSUPPORT 135 +#endif +#ifndef EPROTOTYPE +#define EPROTOTYPE 136 +#endif +#ifndef ETIME +#define ETIME 137 +#endif +#ifndef ETIMEDOUT +#define ETIMEDOUT 138 +#endif +#ifndef ETXTBSY +#define ETXTBSY 139 +#endif +#ifndef EWOULDBLOCK +#define EWOULDBLOCK 140 +#endif + + +/* Windows does not support "ll" format printf length modifiers. Mingw + * therefore maps these to the Windows specific I64 length modifier. That + * won't work for us, as we use our own printf backend on Windows, which works + * just fine with "ll". */ +#undef PRId64 +#define PRId64 "lld" +#undef PRId64 +#define PRId64 "lld" +#undef PRIdLEAST64 +#define PRIdLEAST64 "lld" +#undef PRIdFAST64 +#define PRIdFAST64 "lld" +#undef PRIdMAX +#define PRIdMAX "lld" +#undef PRIi64 +#define PRIi64 "lli" +#undef PRIiLEAST64 +#define PRIiLEAST64 "lli" +#undef PRIiFAST64 +#define PRIiFAST64 "lli" +#undef PRIiMAX +#define PRIiMAX "lli" +#undef PRIo64 +#define PRIo64 "llo" +#undef PRIoLEAST64 +#define PRIoLEAST64 "llo" +#undef PRIoFAST64 +#define PRIoFAST64 "llo" +#undef PRIoMAX +#define PRIoMAX "llo" +#undef PRIu64 +#define PRIu64 "llu" +#undef PRIuLEAST64 +#define PRIuLEAST64 "llu" +#undef PRIuFAST64 +#define PRIuFAST64 "llu" +#undef PRIuMAX +#define PRIuMAX "llu" +#undef PRIx64 +#define PRIx64 "llx" +#undef PRIxLEAST64 +#define PRIxLEAST64 "llx" +#undef PRIxFAST64 +#define PRIxFAST64 "llx" +#undef PRIxMAX +#define PRIxMAX "llx" +#undef PRIX64 +#define PRIX64 "llX" +#undef PRIXLEAST64 +#define PRIXLEAST64 "llX" +#undef PRIXFAST64 +#define PRIXFAST64 "llX" +#undef PRIXMAX +#define PRIXMAX "llX" + +#ifdef _WIN64 +# undef PRIdPTR +# define PRIdPTR "lld" +# undef PRIiPTR +# define PRIiPTR "lli" +# undef PRIoPTR +# define PRIoPTR "llo" +# undef PRIuPTR +# define PRIuPTR "llu" +# undef PRIxPTR +# define PRIxPTR "llx" +# undef PRIXPTR +# define PRIXPTR "llX" +#endif /* _WIN64 */ + +#endif /** WINDOWS_H_ @}*/ |