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