1 #ifndef _COMMON_H_ 2 #define _COMMON_H_ 3 4 #include <limits.h> 5 #ifdef HAVE_CONFIG_H 6 #include "config.h" 7 #endif /* HAVE_CONFIG_H */ 8 9 /* There are many differeces between Linux and Windows. 10 * And we defined things here to unify interfaces, 11 * but it doesn't seem to be very good. */ 12 13 #ifdef WIN32 /* For Windows below. */ 14 15 #ifdef WIN64 16 #ifdef _WIN32_WINNT 17 #undef _WIN32_WINNT 18 #endif 19 #define _WIN32_WINNT 0x0600 20 #endif 21 22 #include <stdlib.h> 23 #include <winsock2.h> /* fd_set, struct sockaddr_in, */ 24 #include <windows.h> /* For many things */ 25 #include <wininet.h> /* Some internet API, include InternetOpen(), InternetOpenUrl(), etc. */ 26 #include <Shlwapi.h> /* PathMatchSpec() */ 27 #include <ws2tcpip.h> /* struct sockaddr_in6 */ 28 29 /* In Linux, the last prarmeter of 'send' is mostly MSG_NOSIGNAL(0x4000) (defined in linux headers), 30 * but in Windows, no this macro. And this prarmeter is zero, mostly. 31 * So we define this macro for Windows. 32 */ 33 34 typedef int socklen_t; 35 36 /* In Windows, the indetifer of a thread is just a 'HANDLE'. */ 37 typedef HANDLE ThreadHandle; 38 /* And Mutex */ 39 typedef HANDLE MutexHandle; 40 41 /* Files */ 42 typedef HANDLE FileHandle; 43 #define INVALID_FILE ((FileHandle)NULL) 44 typedef HANDLE MappingHandle; 45 #define INVALID_MAP ((MappingHandle)NULL) 46 #define INVALID_MAPPING_FILE (NULL) 47 48 /* TCP_TIME_OUT, used as a return value */ 49 #define TCP_TIME_OUT WSAETIMEDOUT 50 51 #define GET_LAST_ERROR() (WSAGetLastError()) 52 #define SET_LAST_ERROR(i) (WSASetLastError(i)) 53 54 /* Close a socket */ 55 #define CLOSE_SOCKET(s) (closesocket(s)) 56 57 /* Threading */ 58 #define CREATE_THREAD(func_ptr, para_ptr, result_holder) (result_holder) = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)(func_ptr), (para_ptr), 0, NULL); 59 #define EXIT_THREAD(r) return (r) 60 #define DETACH_THREAD(t) CloseHandle(t) 61 62 /* Mutex */ 63 #define CREATE_MUTEX(m) ((m) = CreateMutex(NULL, FALSE, NULL)) 64 #define GET_MUTEX(m) (WaitForSingleObject((m), INFINITE)) 65 #define GET_MUTEX_TRY(m) (WaitForSingleObject((m), 0)) 66 #define RELEASE_MUTEX(m) (ReleaseMutex(m)) 67 #define DESTROY_MUTEX(m) (CloseHandle(m)) 68 #define GET_MUTEX_FAILED WAIT_TIMEOUT /* Used as return value */ 69 70 /* CRITICAL_SECTION */ 71 #define CRITICAL_SECTION_INIT(c, spin_count) (InitializeCriticalSectionAndSpinCount(&(c), (spin_count))) 72 #define ENTER_CRITICAL_SECTION(c) (EnterCriticalSection(&(c))) 73 #define ENTER_CRITICAL_SECTION_TRY(c) (TryEnterCriticalSection(&(c))) 74 #define CRITICAL_SECTION_TRY_SUCCEED(ret) ((ret) != 0) 75 #define LEAVE_CRITICAL_SECTION(c) (LeaveCriticalSection(&(c))) 76 #define DELETE_CRITICAL_SECTION(c) (DeleteCriticalSection(&(c))) 77 78 /* File and mapping handles*/ 79 #define OPEN_FILE(file) CreateFile((file), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL) 80 #define CREATE_FILE_MAPPING(handle, size) CreateFileMapping((handle), NULL, PAGE_READWRITE, 0, size, NULL); 81 #define MPA_FILE(handle, size) MapViewOfFile((handle), FILE_MAP_WRITE, 0, 0, 0) 82 83 #define UNMAP_FILE(start, size) UnmapViewOfFile(start) 84 #define DESTROY_MAPPING(handle) CloseHandle(handle) 85 #define CLOSE_FILE(handle) CloseHandle(handle) 86 87 #define PATH_SLASH_CH '\\' 88 #define PATH_SLASH_STR "\\" 89 90 /* Fill Address */ 91 #define FILL_ADDR4(addr_struct, family, address_string, port) (addr_struct).sin_family = (family); \ 92 (addr_struct).sin_addr.S_un.S_addr = inet_addr(address_string); \ 93 (addr_struct).sin_port = htons(port); 94 /* Suspend current thread for some milliseconds */ 95 #define SLEEP(i) (Sleep(i)) 96 97 #define GET_TEMP_DIR() getenv("TEMP") 98 99 #define GET_THREAD_ID() ((int)GetCurrentThreadId()) 100 101 /* Wildcard match function */ 102 #define WILDCARD_MATCH(p, s) PathMatchSpec((s), (p)) 103 #define WILDCARD_MATCHED TRUE /* Used as return value */ 104 105 #define CONNECT_FUNCTION_BLOCKED WSAEWOULDBLOCK 106 107 typedef short sa_family_t; 108 109 #define ExitThisThread() (ExitThread(0)) 110 111 #else /* For Linux below */ 112 113 #include <netinet/in.h> /* For struct 'sockaddr_in' */ 114 115 /* For function 'socket', 'bind', 'connect', 'send', 'recv', 116 * 'sendto', 'recvfrom', 'setsockopt', 'shutdown'. */ 117 #include <sys/socket.h> 118 119 #include <unistd.h> /* For function 'close' , 'sleep' */ 120 #include <errno.h> /* For extern variable 'errno'. */ 121 #include <arpa/inet.h> /* For function 'inet_addr'. */ 122 #include <pthread.h> /* Multithread support. */ 123 124 #include <sys/types.h> /* struct stat */ 125 #include <sys/stat.h> /* stat() */ 126 127 #include <sys/mman.h> /* mmap */ 128 #include <fcntl.h> 129 130 #ifdef HAVE_SYS_SYSCALL_H 131 #include <sys/syscall.h> /* syscall */ 132 #endif /* HAVE_SYS_SYSCALL_H */ 133 134 #include <pwd.h> /* struct passwd */ 135 136 #include <fnmatch.h> /* fnmatch() */ 137 138 /* In Linux, the type of socket is 'int'. */ 139 typedef int SOCKET; 140 141 /* We use pthread to implement multi threads */ 142 /* The indetifer of pthread is 'pthread_t'. */ 143 typedef pthread_t ThreadHandle; 144 /* And mutex */ 145 typedef pthread_mutex_t MutexHandle; 146 /* spin lock */ 147 #ifdef HAVE_PTHREAD_SPIN_INIT 148 typedef pthread_spinlock_t SpinHandle; 149 #else 150 typedef pthread_mutex_t SpinHandle; 151 #endif 152 153 /* There are so many HANDLEs are just ints in Linux. */ 154 typedef int FileHandle; /* The type of return value of open() */ 155 #define INVALID_FILE ((FileHandle)(-1)) 156 157 typedef int MappingHandle; 158 #define INVALID_MAP ((MappingHandle)(-1)) 159 #define INVALID_MAPPING_FILE ((void *)(-1)) 160 161 /* TCP_TIME_OUT, used as a return value */ 162 #define TCP_TIME_OUT EAGAIN 163 164 #define GET_LAST_ERROR() errno 165 #define SET_LAST_ERROR(i) (errno = (i)) 166 167 /* These are defined in 'windows.h'. */ 168 #define INVALID_SOCKET ((SOCKET)(~0)) 169 #define SOCKET_ERROR (-1) 170 171 /* Close a socket */ 172 #define CLOSE_SOCKET(s) (close(s)) 173 174 /* Boolean */ 175 #define BOOL int 176 #define FALSE 0 177 #define TRUE (!0) 178 179 180 #ifndef SO_DONTLINGER 181 #define SO_DONTLINGER ((unsigned int) (~SO_LINGER)) 182 #endif 183 184 /* pthread */ 185 #define CREATE_THREAD(func_ptr, para_ptr, return_value) (pthread_create(&return_value, NULL, (void *(*)())(func_ptr), (para_ptr))) 186 #define EXIT_THREAD(r) pthread_exit(r) 187 #define DETACH_THREAD(t) pthread_detach(t) 188 189 /* mutex */ 190 #define CREATE_MUTEX(m) (pthread_mutex_init(&(m), NULL)) 191 #define GET_MUTEX(m) (pthread_mutex_lock(&(m))) 192 #define GET_MUTEX_TRY(m) (pthread_mutex_trylock(&(m))) 193 #define RELEASE_MUTEX(m) (pthread_mutex_unlock(&(m))) 194 #define DESTROY_MUTEX(m) (pthread_mutex_destroy(&(m))) 195 #define GET_MUTEX_FAILED (!0) 196 197 /* spin lock */ 198 #ifdef HAVE_PTHREAD_SPIN_INIT 199 #define CREATE_SPIN(s) (pthread_spin_init(&(s), PTHREAD_PROCESS_PRIVATE)) 200 #define LOCK_SPIN(s) (pthread_spin_lock(&(s))) 201 #define LOCK_SPIN_TRY(s) (pthread_spin_trylock(&(s))) 202 #define SPIN_TRY_SUCCEED(ret) ((ret) == 0) 203 #define UNLOCK_SPIN(s) (pthread_spin_unlock(&(s))) 204 #define DESTROY_SPIN(s) (pthread_spin_destroy(&(s))) 205 #else /*HAVE_PTHREAD_SPIN_INIT */ 206 #define CREATE_SPIN(s) (pthread_mutex_init(&(s), NULL)) 207 #define LOCK_SPIN(s) (pthread_mutex_lock(&(s))) 208 #define LOCK_SPIN_TRY(s) (pthread_mutex_trylock(&(s))) 209 #define SPIN_TRY_SUCCEED(ret) ((ret) == 0) 210 #define UNLOCK_SPIN(s) (pthread_mutex_unlock(&(s))) 211 #define DESTROY_SPIN(s) (pthread_mutex_destroy(&(s))) 212 #endif /*HAVE_PTHREAD_SPIN_INIT */ 213 214 /* File and Mapping */ 215 /* In Linux, there is no a long process to map a file like Windows. */ 216 #define OPEN_FILE(file) (open((file), O_RDWR | O_CREAT, S_IRWXU)) 217 #define CREATE_FILE_MAPPING(handle, size) (lseek((handle), size, SEEK_SET), write((handle), "\0", 1), (handle)) 218 #define MPA_FILE(handle, size) (mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, (handle), 0)) 219 #define UNMAP_FILE(start, size) (munmap(start, size)) 220 #define DESTROY_MAPPING(handle) /* Nothing */ 221 #define CLOSE_FILE(handle) (close(handle)) 222 223 #define PATH_SLASH_CH '/' 224 #define PATH_SLASH_STR "/" 225 226 #define FILL_ADDR4(addr_struct, family, address_string, port) (addr_struct).sin_family = (family); \ 227 (addr_struct).sin_addr.s_addr = inet_addr(address_string); \ 228 (addr_struct).sin_port = htons(port); 229 230 /* Suspend current thread for some milliseconds */ 231 #define SLEEP(i) do \ 232 { \ 233 int Count = 1000; \ 234 do \ 235 { \ 236 usleep(i); \ 237 --Count; \ 238 } while( Count > 0 ); \ 239 } while( 0 ) 240 241 /* As the name suggests */ 242 #define GET_TEMP_DIR() "/tmp" 243 244 #ifdef HAVE_SYS_SYSCALL_H 245 #define GET_THREAD_ID() syscall(__NR_gettid) 246 #else /* HAVE_SYS_SYSCALL_H */ 247 #define GET_THREAD_ID() (-1) 248 #endif /* HAVE_SYS_SYSCALL_H */ 249 250 #define WILDCARD_MATCH(p, s) fnmatch((p), (s), FNM_NOESCAPE) 251 #define WILDCARD_MATCHED 0 252 253 #define CONNECT_FUNCTION_BLOCKED EINPROGRESS 254 255 #define ExitThisThread() (pthread_exit(NULL)) 256 257 #endif /* WIN32 */ 258 259 #ifdef WIN32 260 typedef CRITICAL_SECTION EFFECTIVE_LOCK; 261 #define EFFECTIVE_LOCK_INIT(l) CRITICAL_SECTION_INIT((l), 1024) 262 #define EFFECTIVE_LOCK_GET(l) ENTER_CRITICAL_SECTION(l) 263 #define EFFECTIVE_LOCK_TRY_GET(l) ENTER_CRITICAL_SECTION_TRY(l) 264 #define EFFECTIVE_LOCK_TRY_SUCCEED(ret) CRITICAL_SECTION_TRY_SUCCEED(ret) 265 #define EFFECTIVE_LOCK_RELEASE(l) LEAVE_CRITICAL_SECTION(l) 266 #define EFFECTIVE_LOCK_DESTROY(l) DELETE_CRITICAL_SECTION(l) 267 #else /* WIN32 */ 268 typedef SpinHandle EFFECTIVE_LOCK; 269 #define EFFECTIVE_LOCK_INIT(l) CREATE_SPIN(l) 270 #define EFFECTIVE_LOCK_GET(l) LOCK_SPIN(l) 271 #define EFFECTIVE_LOCK_TRY_GET(l) LOCK_SPIN_TRY(l) 272 #define EFFECTIVE_LOCK_TRY_SUCCEED(ret) SPIN_TRY_SUCCEED(ret) 273 #define EFFECTIVE_LOCK_RELEASE(l) UNLOCK_SPIN(l) 274 #define EFFECTIVE_LOCK_DESTROY(l) DESTROY_SPIN(l) 275 #endif /* WIN32 */ 276 277 #ifdef WIN32 278 #define GetFileDirectory(out) (GetModulePath(out, sizeof(out))) 279 #else /* WIN32 */ 280 #define GetFileDirectory(out) (GetConfigDirectory(out)) 281 #endif /* WIN32 */ 282 283 #define INVALID_THREAD ((ThreadHandle)NULL) 284 285 #ifndef MSG_NOSIGNAL 286 #define MSG_NOSIGNAL 0 287 #endif /* MSG_NOSIGNAL */ 288 289 #ifndef MSG_MORE 290 #define MSG_MORE 0 291 #endif /* MSG_MORE */ 292 293 #ifndef MSG_WAITALL 294 #define MSG_WAITALL 0 295 #endif /* MSG_WAITALL */ 296 297 /* Unified interfaces end */ 298 299 /* something is STILL on some state */ 300 #define __STILL 301 302 #ifdef HAVE_STDINT_H 303 #include <stdint.h> 304 #else 305 #ifndef HAVE_CONFIG_H 306 #ifndef __USE_MISC 307 308 #if (INT_MAX == 2147483647) 309 #define int32_t int 310 #define uint32_t unsigned int 311 #define UINT32_T_MAX 0xFFFFFFFF 312 #endif 313 314 #if (SHRT_MAX == 32767) 315 #define int16_t short 316 #define uint16_t unsigned short 317 #endif 318 319 #endif 320 #endif 321 #endif 322 323 #ifndef HAVE_IN_PORT_T 324 typedef uint16_t in_port_t; 325 #endif 326 327 /* Parameters' tag */ 328 #ifndef __in 329 #define __in 330 #endif /* __in */ 331 332 #ifndef __in_opt 333 #define __in_opt 334 #endif /* __in_opt */ 335 336 #ifndef __out 337 #define __out 338 #endif /* __out */ 339 340 #ifndef __out_opt 341 #define __out_opt 342 #endif /* __out_opt */ 343 344 #ifndef __inout 345 #define __inout 346 #endif /* __inout */ 347 348 #ifndef __inout_opt 349 #define __inout_opt 350 #endif /* __inout_opt */ 351 352 #define LENGTH_OF_IPV6_ADDRESS_ASCII (sizeof("XXXX:XXXX:XXXX:XXXX:XXXX:XXXX:xxx.xxx.xxx.xxx")) 353 #define LENGTH_OF_IPV4_ADDRESS_ASCII (sizeof("xxx.xxx.xxx.xxx")) 354 355 typedef struct _Address_Type{ 356 357 /* Union of address of IPv4 and IPv6 */ 358 union { 359 struct sockaddr_in Addr4; 360 struct sockaddr_in6 Addr6; 361 } Addr; 362 363 /* Although there is a `family' field in both `struct sockaddr_in' and 364 * `struct sockaddr_in6', we also add it out here. 365 */ 366 sa_family_t family; 367 368 } Address_Type; 369 370 #endif /* _COMMON_H_ */ 371