1 /*
2   This file is part of libmicrohttpd
3   Copyright (C) 2014 Karlson2k (Evgeny Grin)
4 
5   This library is free software; you can redistribute it and/or
6   modify it under the terms of the GNU Lesser General Public
7   License as published by the Free Software Foundation; either
8   version 2.1 of the License, or (at your option) any later version.
9 
10   This library is distributed in the hope that it will be useful,
11   but WITHOUT ANY WARRANTY; without even the implied warranty of
12   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13   Lesser General Public License for more details.
14 
15   You should have received a copy of the GNU Lesser General Public
16   License along with this library.
17   If not, see <http://www.gnu.org/licenses/>.
18 */
19 
20 /**
21  * @file include/platform_interface.h
22  * @brief  internal platform abstraction functions
23  * @author Karlson2k (Evgeny Grin)
24  */
25 
26 #ifndef MHD_PLATFORM_INTERFACE_H
27 #define MHD_PLATFORM_INTERFACE_H
28 
29 #include "platform.h"
30 #if defined(_WIN32) && !defined(__CYGWIN__)
31 #include "w32functions.h"
32 #endif
33 
34 /* *****************************
35      General function mapping
36    *****************************/
37 #if !defined(_WIN32) || defined(__CYGWIN__)
38 /**
39  * Check two strings case-insensitive equality
40  * @param a first string to check
41  * @param b second string to check
42  * @return boolean true if strings are equal, boolean false if strings are unequal
43  */
44 #define MHD_str_equal_caseless_(a,b) (0==strcasecmp((a),(b)))
45 #else
46 /**
47  * Check two strings case-insensitive equality
48  * @param a first string to check
49  * @param b second string to check
50  * @return boolean true if strings are equal, boolean false if strings are unequal
51  */
52 #define MHD_str_equal_caseless_(a,b) (0==_stricmp((a),(b)))
53 #endif
54 
55 #if !defined(_WIN32) || defined(__CYGWIN__)
56 /**
57  * Check not more than n chars in two strings case-insensitive equality
58  * @param a first string to check
59  * @param b second string to check
60  * @param n maximum number of chars to check
61  * @return boolean true if strings are equal, boolean false if strings are unequal
62  */
63 #define MHD_str_equal_caseless_n_(a,b,n) (0==strncasecmp((a),(b),(n)))
64 #else
65 /**
66  * Check not more than n chars in two strings case-insensitive equality
67  * @param a first string to check
68  * @param b second string to check
69  * @param n maximum number of chars to check
70  * @return boolean true if strings are equal, boolean false if strings are unequal
71  */
72 #define MHD_str_equal_caseless_n_(a,b,n) (0==_strnicmp((a),(b),(n)))
73 #endif
74 
75 /* Platform-independent snprintf name */
76 #if !defined(_WIN32) || defined(__CYGWIN__)
77 #define MHD_snprintf_ snprintf
78 #else
79 #define MHD_snprintf_ W32_snprintf
80 #endif
81 
82 
83 
84 /* MHD_socket_close_(fd) close any FDs (non-W32) / close only socket FDs (W32) */
85 #if !defined(_WIN32) || defined(__CYGWIN__)
86 #define MHD_socket_close_(fd) close((fd))
87 #else
88 #define MHD_socket_close_(fd) closesocket((fd))
89 #endif
90 
91 /* MHD_socket_errno_ is errno of last function (non-W32) / errno of last socket function (W32) */
92 #if !defined(_WIN32) || defined(__CYGWIN__)
93 #define MHD_socket_errno_ errno
94 #else
95 #define MHD_socket_errno_ MHD_W32_errno_from_winsock_()
96 #endif
97 
98 /* MHD_socket_last_strerr_ is description string of last errno (non-W32) /
99  *                            description string of last socket error (W32) */
100 #if !defined(_WIN32) || defined(__CYGWIN__)
101 #define MHD_socket_last_strerr_() strerror(errno)
102 #else
103 #define MHD_socket_last_strerr_() MHD_W32_strerror_last_winsock_()
104 #endif
105 
106 /* MHD_strerror_ is strerror (both non-W32/W32) */
107 #if !defined(_WIN32) || defined(__CYGWIN__)
108 #define MHD_strerror_(errnum) strerror((errnum))
109 #else
110 #define MHD_strerror_(errnum) MHD_W32_strerror_((errnum))
111 #endif
112 
113 /* MHD_set_socket_errno_ set errno to errnum (non-W32) / set socket last error to errnum (W32) */
114 #if !defined(_WIN32) || defined(__CYGWIN__)
115 #define MHD_set_socket_errno_(errnum) errno=(errnum)
116 #else
117 #define MHD_set_socket_errno_(errnum) MHD_W32_set_last_winsock_error_((errnum))
118 #endif
119 
120 /* MHD_SYS_select_ is wrapper macro for system select() function */
121 #if !defined(MHD_WINSOCK_SOCKETS)
122 #define MHD_SYS_select_(n,r,w,e,t) select((n),(r),(w),(e),(t))
123 #else
124 #define MHD_SYS_select_(n,r,w,e,t) select((int)0,(r),(w),(e),(t))
125 #endif
126 
127 #if defined(HAVE_POLL)
128 /* MHD_sys_poll_ is wrapper macro for system poll() function */
129 #if !defined(MHD_WINSOCK_SOCKETS)
130 #define MHD_sys_poll_ poll
131 #else  /* MHD_WINSOCK_SOCKETS */
132 #define MHD_sys_poll_ WSAPoll
133 #endif /* MHD_WINSOCK_SOCKETS */
134 #endif /* HAVE_POLL */
135 
136 /* MHD_pipe_ create pipe (!MHD_DONT_USE_PIPES) /
137  *           create two connected sockets (MHD_DONT_USE_PIPES) */
138 #ifndef MHD_DONT_USE_PIPES
139 #define MHD_pipe_(fdarr) pipe((fdarr))
140 #else /* MHD_DONT_USE_PIPES */
141 #if !defined(_WIN32) || defined(__CYGWIN__)
142 #define MHD_pipe_(fdarr) socketpair(AF_LOCAL, SOCK_STREAM, 0, (fdarr))
143 #else /* !defined(_WIN32) || defined(__CYGWIN__) */
144 #define MHD_pipe_(fdarr) MHD_W32_pair_of_sockets_((fdarr))
145 #endif /* !defined(_WIN32) || defined(__CYGWIN__) */
146 #endif /* MHD_DONT_USE_PIPES */
147 
148 /* MHD_pipe_errno_ is errno of last function (!MHD_DONT_USE_PIPES) /
149  *                    errno of last emulated pipe function (MHD_DONT_USE_PIPES) */
150 #ifndef MHD_DONT_USE_PIPES
151 #define MHD_pipe_errno_ errno
152 #else
153 #define MHD_pipe_errno_ MHD_socket_errno_
154 #endif
155 
156 /* MHD_pipe_last_strerror_ is description string of last errno (!MHD_DONT_USE_PIPES) /
157  *                            description string of last pipe error (MHD_DONT_USE_PIPES) */
158 #ifndef MHD_DONT_USE_PIPES
159 #define MHD_pipe_last_strerror_() strerror(errno)
160 #else
161 #define MHD_pipe_last_strerror_() MHD_socket_last_strerr_()
162 #endif
163 
164 /* MHD_pipe_write_ write data to real pipe (!MHD_DONT_USE_PIPES) /
165  *                 write data to emulated pipe (MHD_DONT_USE_PIPES) */
166 #ifndef MHD_DONT_USE_PIPES
167 #define MHD_pipe_write_(fd, ptr, sz) write((fd), (const void*)(ptr), (sz))
168 #else
169 #define MHD_pipe_write_(fd, ptr, sz) send((fd), (const char*)(ptr), (sz), 0)
170 #endif
171 
172 /* MHD_pipe_read_ read data from real pipe (!MHD_DONT_USE_PIPES) /
173  *                read data from emulated pipe (MHD_DONT_USE_PIPES) */
174 #ifndef MHD_DONT_USE_PIPES
175 #define MHD_pipe_read_(fd, ptr, sz) read((fd), (void*)(ptr), (sz))
176 #else
177 #define MHD_pipe_read_(fd, ptr, sz) recv((fd), (char*)(ptr), (sz), 0)
178 #endif
179 
180 /* MHD_pipe_close_(fd) close any FDs (non-W32) /
181  *                     close emulated pipe FDs (W32) */
182 #ifndef MHD_DONT_USE_PIPES
183 #define MHD_pipe_close_(fd) close((fd))
184 #else
185 #define MHD_pipe_close_(fd) MHD_socket_close_((fd))
186 #endif
187 
188 /* MHD_INVALID_PIPE_ is a value of bad pipe FD */
189 #ifndef MHD_DONT_USE_PIPES
190 #define MHD_INVALID_PIPE_ (-1)
191 #else
192 #define MHD_INVALID_PIPE_ MHD_INVALID_SOCKET
193 #endif
194 
195 #if !defined(_WIN32) || defined(__CYGWIN__)
196 #define MHD_random_() random()
197 #else
198 #define MHD_random_() MHD_W32_random_()
199 #endif
200 
201 #if defined(MHD_USE_POSIX_THREADS)
202 typedef pthread_t MHD_thread_handle_;
203 #elif defined(MHD_USE_W32_THREADS)
204 #include <windows.h>
205 typedef HANDLE MHD_thread_handle_;
206 #else
207 #error "No threading API is available."
208 #endif
209 
210 #if defined(MHD_USE_POSIX_THREADS)
211 #define MHD_THRD_RTRN_TYPE_ void*
212 #define MHD_THRD_CALL_SPEC_
213 #elif defined(MHD_USE_W32_THREADS)
214 #define MHD_THRD_RTRN_TYPE_ unsigned
215 #define MHD_THRD_CALL_SPEC_ __stdcall
216 #endif
217 
218 #if defined(MHD_USE_POSIX_THREADS)
219 /**
220  * Wait until specified thread is ended
221  * @param thread ID to watch
222  * @return zero on success, nonzero on failure
223  */
224 #define MHD_join_thread_(thread) pthread_join((thread), NULL)
225 #elif defined(MHD_USE_W32_THREADS)
226 /**
227  * Wait until specified thread is ended
228  * Close thread handle on success
229  * @param thread handle to watch
230  * @return zero on success, nonzero on failure
231  */
232 #define MHD_join_thread_(thread) (WAIT_OBJECT_0 == WaitForSingleObject((thread), INFINITE) ? (CloseHandle((thread)), 0) : 1 )
233 #endif
234 
235 #if defined(MHD_USE_W32_THREADS)
236 #define MHD_W32_MUTEX_ 1
237 #include <windows.h>
238 typedef CRITICAL_SECTION MHD_mutex_;
239 #elif defined(HAVE_PTHREAD_H) && defined(MHD_USE_POSIX_THREADS)
240 #define MHD_PTHREAD_MUTEX_ 1
241 typedef pthread_mutex_t MHD_mutex_;
242 #else
243 #error "No base mutex API is available."
244 #endif
245 
246 #if defined(MHD_PTHREAD_MUTEX_)
247 /**
248  * Create new mutex.
249  * @param mutex pointer to the mutex
250  * @return #MHD_YES on success, #MHD_NO on failure
251  */
252 #define MHD_mutex_create_(mutex) \
253   ((0 == pthread_mutex_init ((mutex), NULL)) ? MHD_YES : MHD_NO)
254 #elif defined(MHD_W32_MUTEX_)
255 /**
256  * Create new mutex.
257  * @param mutex pointer to mutex
258  * @return #MHD_YES on success, #MHD_NO on failure
259  */
260 #define MHD_mutex_create_(mutex) \
261   ((NULL != (mutex) && 0 != InitializeCriticalSectionAndSpinCount((mutex),2000)) ? MHD_YES : MHD_NO)
262 #endif
263 
264 #if defined(MHD_PTHREAD_MUTEX_)
265 /**
266  * Destroy previously created mutex.
267  * @param mutex pointer to mutex
268  * @return #MHD_YES on success, #MHD_NO on failure
269  */
270 #define MHD_mutex_destroy_(mutex) \
271   ((0 == pthread_mutex_destroy ((mutex))) ? MHD_YES : MHD_NO)
272 #elif defined(MHD_W32_MUTEX_)
273 /**
274  * Destroy previously created mutex.
275  * @param mutex pointer to mutex
276  * @return #MHD_YES on success, #MHD_NO on failure
277  */
278 #define MHD_mutex_destroy_(mutex) \
279   ((NULL != (mutex)) ? (DeleteCriticalSection(mutex), MHD_YES) : MHD_NO)
280 #endif
281 
282 #if defined(MHD_PTHREAD_MUTEX_)
283 /**
284  * Acquire lock on previously created mutex.
285  * If mutex was already locked by other thread, function
286  * blocks until mutex becomes available.
287  * @param mutex pointer to mutex
288  * @return #MHD_YES on success, #MHD_NO on failure
289  */
290 #define MHD_mutex_lock_(mutex) \
291   ((0 == pthread_mutex_lock((mutex))) ? MHD_YES : MHD_NO)
292 #elif defined(MHD_W32_MUTEX_)
293 /**
294  * Acquire lock on previously created mutex.
295  * If mutex was already locked by other thread, function
296  * blocks until mutex becomes available.
297  * @param mutex pointer to mutex
298  * @return #MHD_YES on success, #MHD_NO on failure
299  */
300 #define MHD_mutex_lock_(mutex) \
301   ((NULL != (mutex)) ? (EnterCriticalSection((mutex)), MHD_YES) : MHD_NO)
302 #endif
303 
304 #if defined(MHD_PTHREAD_MUTEX_)
305 /**
306  * Try to acquire lock on previously created mutex.
307  * Function returns immediately.
308  * @param mutex pointer to mutex
309  * @return #MHD_YES if mutex is locked, #MHD_NO if
310  * mutex was not locked.
311  */
312 #define MHD_mutex_trylock_(mutex) \
313   ((0 == pthread_mutex_trylock((mutex))) ? MHD_YES : MHD_NO)
314 #elif defined(MHD_W32_MUTEX_)
315 /**
316  * Try to acquire lock on previously created mutex.
317  * Function returns immediately.
318  * @param mutex pointer to mutex
319  * @return #MHD_YES if mutex is locked, #MHD_NO if
320  * mutex was not locked.
321  */
322 #define MHD_mutex_trylock_(mutex) \
323   ((NULL != (mutex) && 0 != TryEnterCriticalSection ((mutex))) ? MHD_YES : MHD_NO)
324 #endif
325 
326 #if defined(MHD_PTHREAD_MUTEX_)
327 /**
328  * Unlock previously created and locked mutex.
329  * @param mutex pointer to mutex
330  * @return #MHD_YES on success, #MHD_NO on failure
331  */
332 #define MHD_mutex_unlock_(mutex) \
333   ((0 == pthread_mutex_unlock((mutex))) ? MHD_YES : MHD_NO)
334 #elif defined(MHD_W32_MUTEX_)
335 /**
336  * Unlock previously created and locked mutex.
337  * @param mutex pointer to mutex
338  * @return #MHD_YES on success, #MHD_NO on failure
339  */
340 #define MHD_mutex_unlock_(mutex) \
341   ((NULL != (mutex)) ? (LeaveCriticalSection((mutex)), MHD_YES) : MHD_NO)
342 #endif
343 
344 #endif // MHD_PLATFORM_INTERFACE_H
345