8e6fd80b1dba077431d7ba15b6e23be602e05c4f
[strongswan.git] / src / libstrongswan / utils / windows.h
1 /*
2 * Copyright (C) 2013 Martin Willi
3 * Copyright (C) 2013 revosec AG
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 * for more details.
14 */
15
16 /**
17 * @defgroup windows windows
18 * @{ @ingroup utils
19 */
20
21 #ifndef WINDOWS_H_
22 #define WINDOWS_H_
23
24 #include <winsock2.h>
25 #include <ws2tcpip.h>
26 #include <direct.h>
27 #include <inttypes.h>
28
29 /* undef Windows variants evaluating values more than once */
30 #undef min
31 #undef max
32
33 /* interface is defined as an alias to "struct" in basetypes.h, but
34 * we use it here and there as ordinary identifier. */
35 #undef interface
36
37 /* used by Windows API, but we have our own */
38 #undef CALLBACK
39
40 /* UID/GID types for capabilities, even if not supported */
41 typedef u_int uid_t;
42 typedef u_int gid_t;
43
44 /**
45 * Initialize Windows libraries
46 */
47 void windows_init();
48
49 /**
50 * Deinitialize windows libraries
51 */
52 void windows_deinit();
53
54 /**
55 * Replacement for random(3)
56 */
57 static inline long random(void)
58 {
59 return rand();
60 }
61
62 /**
63 * Replacement for srandom(3)
64 */
65 static inline void srandom(unsigned int seed)
66 {
67 srand(seed);
68 }
69
70 /**
71 * Replacement of sched_yield(2) from <sched.h>
72 */
73 static inline int sched_yield(void)
74 {
75 Sleep(0);
76 return 0;
77 }
78
79 /**
80 * Replacement of sleep(3), cancellable by thread_cancel()
81 */
82 static inline int sleep(unsigned int seconds)
83 {
84 SleepEx(seconds * 1000, TRUE);
85 return 0;
86 }
87
88 /**
89 * Replacement of usleep(3), cancellable, ms resolution only
90 */
91 int usleep(useconds_t usec);
92
93 /**
94 * strdup(3), the Windows variant can't free(strdup("")) and others
95 */
96 #define strdup strdup_windows
97 static inline char* strdup_windows(const char *src)
98 {
99 size_t len;
100 char *dst;
101
102 len = strlen(src) + 1;
103 dst = malloc(len);
104 memcpy(dst, src, len);
105 return dst;
106 }
107
108 /**
109 * Provided via ws2_32
110 */
111 const char *inet_ntop(int af, const void *src, char *dst, socklen_t size);
112
113 /**
114 * Provided via ws2_32
115 */
116 int inet_pton(int af, const char *src, void *dst);
117
118 /**
119 * Provided by printf hook backend
120 */
121 int asprintf(char **strp, const char *fmt, ...);
122
123 /**
124 * Provided by printf hook backend
125 */
126 int vasprintf(char **strp, const char *fmt, va_list ap);
127
128 /**
129 * timeradd(3) from <sys/time.h>
130 */
131 static inline void timeradd(struct timeval *a, struct timeval *b,
132 struct timeval *res)
133 {
134 res->tv_sec = a->tv_sec + b->tv_sec;
135 res->tv_usec = a->tv_usec + b->tv_usec;
136 if (res->tv_usec >= 1000000)
137 {
138 res->tv_usec -= 1000000;
139 res->tv_sec++;
140 }
141 }
142
143 /**
144 * timersub(3) from <sys/time.h>
145 */
146 static inline void timersub(struct timeval *a, struct timeval *b,
147 struct timeval *res)
148 {
149 res->tv_sec = a->tv_sec - b->tv_sec;
150 res->tv_usec = a->tv_usec - b->tv_usec;
151 if (res->tv_usec < 0)
152 {
153 res->tv_usec += 1000000;
154 res->tv_sec--;
155 }
156 }
157
158 /**
159 * gmtime_r(3) from <time.h>
160 */
161 static inline struct tm *gmtime_r(const time_t *timep, struct tm *result)
162 {
163 struct tm *ret;
164
165 /* gmtime_s() and friends seem not to be implemented/functioning.
166 * Relying on gmtime() on Windows works as well, as it uses thread
167 * specific buffers. */
168 ret = gmtime(timep);
169 if (ret)
170 {
171 memcpy(result, ret, sizeof(*result));
172 }
173 return ret;
174 }
175
176 /**
177 * localtime_r(3) from <time.h>
178 */
179 static inline struct tm *localtime_r(const time_t *timep, struct tm *result)
180 {
181 struct tm *ret;
182
183 /* localtime_s() and friends seem not to be implemented/functioning.
184 * Relying on localtime() on Windows works as well, as it uses thread
185 * specific buffers. */
186 ret = localtime(timep);
187 if (ret)
188 {
189 memcpy(result, ret, sizeof(*result));
190 }
191 return ret;
192 }
193
194 /**
195 * setenv(3) from <stdlib.h>, overwrite flag is ignored
196 */
197 static inline int setenv(const char *name, const char *value, int overwrite)
198 {
199 if (SetEnvironmentVariableA(name, value) == 0)
200 { /* failed */
201 return -1;
202 }
203 return 0;
204 }
205
206 /**
207 * dlerror(3) from <dlfcn.h>, printing error to an alloca() buffer
208 */
209 #define dlerror() \
210 ({ \
211 char buf[128], *out;\
212 ssize_t len; \
213 DWORD err; \
214 err = GetLastError(); \
215 len = FormatMessage(0, NULL, err, 0, buf, sizeof(buf), NULL); \
216 if (len <= 0) \
217 { \
218 len = snprintf(buf, sizeof(buf), "(%u)", err); \
219 } \
220 len++; \
221 out = alloca(len); \
222 memcpy(out, buf, len); \
223 out; \
224 })
225
226 /**
227 * Lazy binding, ignored on Windows
228 */
229 #define RTLD_LAZY 1
230
231 /**
232 * dlopen(3) from <dlfcn.h>
233 */
234 static inline void *dlopen(const char *filename, int flag)
235 {
236 return LoadLibrary(filename);
237 }
238
239 /**
240 * Default handle targeting .exe
241 */
242 #define RTLD_DEFAULT (NULL)
243
244 /**
245 * Find symbol in next library
246 */
247 #define RTLD_NEXT ((void*)~(uintptr_t)0)
248
249 /**
250 * dlsym() from <dlfcn.h>
251 */
252 static inline void *dlsym(void *handle, const char *symbol)
253 {
254 if (handle == RTLD_DEFAULT)
255 {
256 handle = GetModuleHandle(NULL);
257 }
258 else if (handle == RTLD_NEXT)
259 {
260 if (strcmp(symbol, "malloc") == 0 ||
261 strcmp(symbol, "realloc") == 0 ||
262 strcmp(symbol, "free") == 0)
263 {
264 /* for leak-detective */
265 handle = GetModuleHandle("msvcrt");
266 }
267 else
268 {
269 return NULL;
270 }
271 }
272 if (handle)
273 {
274 return GetProcAddress((HMODULE)handle, symbol);
275 }
276 return NULL;
277 }
278
279 /**
280 * dlclose() from <dlfcn.h>
281 */
282 static inline int dlclose(void *handle)
283 {
284 return FreeLibrary((HMODULE)handle);
285 }
286
287 /**
288 * socketpair(2) for SOCK_STREAM, uses TCP on loopback
289 */
290 int socketpair(int domain, int type, int protocol, int sv[2]);
291
292 /**
293 * Map MSG_DONTWAIT to the reserved, but deprecated MSG_INTERRUPT
294 */
295 #define MSG_DONTWAIT MSG_INTERRUPT
296
297 /**
298 * EWOULDBLOCK is EAGAIN on other systems as well
299 */
300 #define EWOULDBLOCK EAGAIN
301
302 /**
303 * ECONNRESET is mapped to something arbitrary. It is returned by
304 * stream->read_all() but should not be mapped from a send/recv WSA error.
305 */
306 #define ECONNRESET ENXIO
307
308 /**
309 * recv(2) with support for MSG_DONTWAIT
310 */
311 #define recv(...) windows_recv(__VA_ARGS__)
312 ssize_t windows_recv(int sockfd, void *buf, size_t len, int flags);
313
314 /**
315 * recvfrom(2) with support for MSG_DONTWAIT
316 */
317 #define recvfrom(...) windows_recvfrom(__VA_ARGS__)
318 ssize_t windows_recvfrom(int sockfd, void *buf, size_t len, int flags,
319 struct sockaddr *src_addr, socklen_t *addrlen);
320
321 /**
322 * recvfrom(2) with support for MSG_DONTWAIT
323 */
324 #define send(...) windows_send(__VA_ARGS__)
325 ssize_t windows_send(int sockfd, const void *buf, size_t len, int flags);
326
327 /**
328 * recvfrom(2) with support for MSG_DONTWAIT
329 */
330 #define sendto(...) windows_send(__VA_ARGS__)
331 ssize_t windows_sendto(int sockfd, const void *buf, size_t len, int flags,
332 const struct sockaddr *dest_addr, socklen_t addrlen);
333
334 /* Windows does not support "ll" format printf length modifiers. Mingw
335 * therefore maps these to the Windows specific I64 length modifier. That
336 * won't work for us, as we use our own printf backend on Windows, which works
337 * just fine with "ll". */
338 #undef PRId64
339 #define PRId64 "lld"
340 #undef PRId64
341 #define PRId64 "lld"
342 #undef PRIdLEAST64
343 #define PRIdLEAST64 "lld"
344 #undef PRIdFAST64
345 #define PRIdFAST64 "lld"
346 #undef PRIdMAX
347 #define PRIdMAX "lld"
348 #undef PRIi64
349 #define PRIi64 "lli"
350 #undef PRIiLEAST64
351 #define PRIiLEAST64 "lli"
352 #undef PRIiFAST64
353 #define PRIiFAST64 "lli"
354 #undef PRIiMAX
355 #define PRIiMAX "lli"
356 #undef PRIo64
357 #define PRIo64 "llo"
358 #undef PRIoLEAST64
359 #define PRIoLEAST64 "llo"
360 #undef PRIoFAST64
361 #define PRIoFAST64 "llo"
362 #undef PRIoMAX
363 #define PRIoMAX "llo"
364 #undef PRIu64
365 #define PRIu64 "llu"
366 #undef PRIuLEAST64
367 #define PRIuLEAST64 "llu"
368 #undef PRIuFAST64
369 #define PRIuFAST64 "llu"
370 #undef PRIuMAX
371 #define PRIuMAX "llu"
372 #undef PRIx64
373 #define PRIx64 "llx"
374 #undef PRIxLEAST64
375 #define PRIxLEAST64 "llx"
376 #undef PRIxFAST64
377 #define PRIxFAST64 "llx"
378 #undef PRIxMAX
379 #define PRIxMAX "llx"
380 #undef PRIX64
381 #define PRIX64 "llX"
382 #undef PRIXLEAST64
383 #define PRIXLEAST64 "llX"
384 #undef PRIXFAST64
385 #define PRIXFAST64 "llX"
386 #undef PRIXMAX
387 #define PRIXMAX "llX"
388
389 #ifdef _WIN64
390 # undef PRIdPTR
391 # define PRIdPTR "lld"
392 # undef PRIiPTR
393 # define PRIiPTR "lli"
394 # undef PRIoPTR
395 # define PRIoPTR "llo"
396 # undef PRIuPTR
397 # define PRIuPTR "llu"
398 # undef PRIxPTR
399 # define PRIxPTR "llx"
400 # undef PRIXPTR
401 # define PRIXPTR "llX"
402 #endif /* _WIN64 */
403
404 #endif /** WINDOWS_H_ @}*/