1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* This Source Code Form is subject to the terms of the Mozilla Public 3 * License, v. 2.0. If a copy of the MPL was not distributed with this 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 5 6 #ifndef nspr_os2_defs_h___ 7 #define nspr_os2_defs_h___ 8 9 #ifndef NO_LONG_LONG 10 #define INCL_LONGLONG 11 #endif 12 #define INCL_DOS 13 #define INCL_DOSPROCESS 14 #define INCL_DOSERRORS 15 #define INCL_WIN 16 #define INCL_WPS 17 #include <os2.h> 18 #include <sys/select.h> 19 20 #include "prio.h" 21 22 #include <errno.h> 23 24 /* 25 * Internal configuration macros 26 */ 27 28 #define PR_LINKER_ARCH "os2" 29 #define _PR_SI_SYSNAME "OS2" 30 #define _PR_SI_ARCHITECTURE "x86" /* XXXMB hardcode for now */ 31 32 #define HAVE_DLL 33 #define _PR_GLOBAL_THREADS_ONLY 34 #undef HAVE_THREAD_AFFINITY 35 #define _PR_HAVE_THREADSAFE_GETHOST 36 #define _PR_HAVE_ATOMIC_OPS 37 #define HAVE_NETINET_TCP_H 38 39 #define HANDLE unsigned long 40 #define HINSTANCE HMODULE 41 42 /* --- Common User-Thread/Native-Thread Definitions --------------------- */ 43 44 /* --- Globals --- */ 45 extern struct PRLock *_pr_schedLock; 46 47 /* --- Typedefs --- */ 48 typedef void (*FiberFunc)(void *); 49 50 #define PR_NUM_GCREGS 8 51 typedef PRInt32 PR_CONTEXT_TYPE[PR_NUM_GCREGS]; 52 #define GC_VMBASE 0x40000000 53 #define GC_VMLIMIT 0x00FFFFFF 54 typedef int (*FARPROC)(); 55 56 #define _MD_MAGIC_THREAD 0x22222222 57 #define _MD_MAGIC_THREADSTACK 0x33333333 58 #define _MD_MAGIC_SEGMENT 0x44444444 59 #define _MD_MAGIC_DIR 0x55555555 60 #define _MD_MAGIC_CV 0x66666666 61 62 struct _MDSemaphore { 63 HEV sem; 64 }; 65 66 struct _MDCPU { 67 int unused; 68 }; 69 70 struct _MDThread { 71 HEV blocked_sema; /* Threads block on this when waiting 72 * for IO or CondVar. 73 */ 74 PRBool inCVWaitQueue; /* PR_TRUE if the thread is in the 75 * wait queue of some cond var. 76 * PR_FALSE otherwise. */ 77 TID handle; /* OS/2 thread handle */ 78 void *sp; /* only valid when suspended */ 79 PRUint32 magic; /* for debugging */ 80 PR_CONTEXT_TYPE gcContext; /* Thread context for GC */ 81 struct PRThread *prev, *next; /* used by the cvar wait queue to 82 * chain the PRThread structures 83 * together */ 84 }; 85 86 struct _MDThreadStack { 87 PRUint32 magic; /* for debugging */ 88 }; 89 90 struct _MDSegment { 91 PRUint32 magic; /* for debugging */ 92 }; 93 94 #undef PROFILE_LOCKS 95 96 struct _MDDir { 97 HDIR d_hdl; 98 union { 99 FILEFINDBUF3 small; 100 FILEFINDBUF3L large; 101 } d_entry; 102 PRBool firstEntry; /* Is this the entry returned 103 * by FindFirstFile()? */ 104 PRUint32 magic; /* for debugging */ 105 }; 106 107 struct _MDCVar { 108 PRUint32 magic; 109 struct PRThread *waitHead, *waitTail; /* the wait queue: a doubly- 110 * linked list of threads 111 * waiting on this condition 112 * variable */ 113 PRIntn nwait; /* number of threads in the 114 * wait queue */ 115 }; 116 117 #define _MD_CV_NOTIFIED_LENGTH 6 118 typedef struct _MDNotified _MDNotified; 119 struct _MDNotified { 120 PRIntn length; /* # of used entries in this 121 * structure */ 122 struct { 123 struct _MDCVar *cv; /* the condition variable notified */ 124 PRIntn times; /* and the number of times notified */ 125 struct PRThread *notifyHead; /* list of threads to wake up */ 126 } cv[_MD_CV_NOTIFIED_LENGTH]; 127 _MDNotified *link; /* link to another of these, or NULL */ 128 }; 129 130 struct _MDLock { 131 HMTX mutex; /* this is recursive on OS/2 */ 132 133 /* 134 * When notifying cvars, there is no point in actually 135 * waking up the threads waiting on the cvars until we've 136 * released the lock. So, we temporarily record the cvars. 137 * When doing an unlock, we'll then wake up the waiting threads. 138 */ 139 struct _MDNotified notified; /* array of conditions notified */ 140 #ifdef PROFILE_LOCKS 141 PRInt32 hitcount; 142 PRInt32 misscount; 143 #endif 144 }; 145 146 struct _MDFileDesc { 147 PRInt32 osfd; /* The osfd can come from one of three spaces: 148 * - For stdin, stdout, and stderr, we are using 149 * the libc file handle (0, 1, 2), which is an int. 150 * - For files and pipes, we are using OS/2 handles, 151 * which is a void*. 152 * - For sockets, we are using int 153 */ 154 }; 155 156 struct _MDProcess { 157 PID pid; 158 }; 159 160 /* --- Misc stuff --- */ 161 #define _MD_GET_SP(thread) (thread)->md.gcContext[6] 162 163 /* --- IO stuff --- */ 164 165 #define _MD_OPEN (_PR_MD_OPEN) 166 #define _MD_OPEN_FILE (_PR_MD_OPEN) 167 #define _MD_READ (_PR_MD_READ) 168 #define _MD_WRITE (_PR_MD_WRITE) 169 #define _MD_WRITEV (_PR_MD_WRITEV) 170 #define _MD_LSEEK (_PR_MD_LSEEK) 171 #define _MD_LSEEK64 (_PR_MD_LSEEK64) 172 extern PRInt32 _MD_CloseFile(PRInt32 osfd); 173 #define _MD_CLOSE_FILE _MD_CloseFile 174 #define _MD_GETFILEINFO (_PR_MD_GETFILEINFO) 175 #define _MD_GETFILEINFO64 (_PR_MD_GETFILEINFO64) 176 #define _MD_GETOPENFILEINFO (_PR_MD_GETOPENFILEINFO) 177 #define _MD_GETOPENFILEINFO64 (_PR_MD_GETOPENFILEINFO64) 178 #define _MD_STAT (_PR_MD_STAT) 179 #define _MD_RENAME (_PR_MD_RENAME) 180 #define _MD_ACCESS (_PR_MD_ACCESS) 181 #define _MD_DELETE (_PR_MD_DELETE) 182 #define _MD_MKDIR (_PR_MD_MKDIR) 183 #define _MD_MAKE_DIR (_PR_MD_MKDIR) 184 #define _MD_RMDIR (_PR_MD_RMDIR) 185 #define _MD_LOCKFILE (_PR_MD_LOCKFILE) 186 #define _MD_TLOCKFILE (_PR_MD_TLOCKFILE) 187 #define _MD_UNLOCKFILE (_PR_MD_UNLOCKFILE) 188 189 /* --- Socket IO stuff --- */ 190 191 /* The ones that don't map directly may need to be re-visited... */ 192 #define _MD_EACCES EACCES 193 #define _MD_EADDRINUSE EADDRINUSE 194 #define _MD_EADDRNOTAVAIL EADDRNOTAVAIL 195 #define _MD_EAFNOSUPPORT EAFNOSUPPORT 196 #define _MD_EAGAIN EWOULDBLOCK 197 #define _MD_EALREADY EALREADY 198 #define _MD_EBADF EBADF 199 #define _MD_ECONNREFUSED ECONNREFUSED 200 #define _MD_ECONNRESET ECONNRESET 201 #define _MD_EFAULT SOCEFAULT 202 #define _MD_EINPROGRESS EINPROGRESS 203 #define _MD_EINTR EINTR 204 #define _MD_EINVAL EINVAL 205 #define _MD_EISCONN EISCONN 206 #define _MD_ENETUNREACH ENETUNREACH 207 #define _MD_ENOENT ENOENT 208 #define _MD_ENOTCONN ENOTCONN 209 #define _MD_ENOTSOCK ENOTSOCK 210 #define _MD_EOPNOTSUPP EOPNOTSUPP 211 #define _MD_EWOULDBLOCK EWOULDBLOCK 212 #define _MD_GET_SOCKET_ERROR() sock_errno() 213 #ifndef INADDR_LOOPBACK /* For some reason this is not defined in OS2 tcpip */ 214 /* #define INADDR_LOOPBACK INADDR_ANY */ 215 #endif 216 217 #define _MD_INIT_FILEDESC(fd) 218 extern void _MD_MakeNonblock(PRFileDesc *f); 219 #define _MD_MAKE_NONBLOCK _MD_MakeNonblock 220 #define _MD_INIT_FD_INHERITABLE (_PR_MD_INIT_FD_INHERITABLE) 221 #define _MD_QUERY_FD_INHERITABLE (_PR_MD_QUERY_FD_INHERITABLE) 222 #define _MD_SHUTDOWN (_PR_MD_SHUTDOWN) 223 #define _MD_LISTEN _PR_MD_LISTEN 224 extern PRInt32 _MD_CloseSocket(PRInt32 osfd); 225 #define _MD_CLOSE_SOCKET _MD_CloseSocket 226 #define _MD_SENDTO (_PR_MD_SENDTO) 227 #define _MD_RECVFROM (_PR_MD_RECVFROM) 228 #define _MD_SOCKETPAIR (_PR_MD_SOCKETPAIR) 229 #define _MD_GETSOCKNAME (_PR_MD_GETSOCKNAME) 230 #define _MD_GETPEERNAME (_PR_MD_GETPEERNAME) 231 #define _MD_GETSOCKOPT (_PR_MD_GETSOCKOPT) 232 #define _MD_SETSOCKOPT (_PR_MD_SETSOCKOPT) 233 234 #define _MD_FSYNC _PR_MD_FSYNC 235 #define _MD_SET_FD_INHERITABLE (_PR_MD_SET_FD_INHERITABLE) 236 237 #ifdef _PR_HAVE_ATOMIC_OPS 238 #define _MD_INIT_ATOMIC() 239 #define _MD_ATOMIC_INCREMENT _PR_MD_ATOMIC_INCREMENT 240 #define _MD_ATOMIC_ADD _PR_MD_ATOMIC_ADD 241 #define _MD_ATOMIC_DECREMENT _PR_MD_ATOMIC_DECREMENT 242 #define _MD_ATOMIC_SET _PR_MD_ATOMIC_SET 243 #endif 244 245 #define _MD_INIT_IO (_PR_MD_INIT_IO) 246 #define _MD_PR_POLL (_PR_MD_PR_POLL) 247 248 #define _MD_SOCKET (_PR_MD_SOCKET) 249 extern PRInt32 _MD_SocketAvailable(PRFileDesc *fd); 250 #define _MD_SOCKETAVAILABLE _MD_SocketAvailable 251 #define _MD_PIPEAVAILABLE _MD_SocketAvailable 252 #define _MD_CONNECT (_PR_MD_CONNECT) 253 extern PRInt32 _MD_Accept(PRFileDesc *fd, PRNetAddr *raddr, PRUint32 *rlen, 254 PRIntervalTime timeout); 255 #define _MD_ACCEPT _MD_Accept 256 #define _MD_BIND (_PR_MD_BIND) 257 #define _MD_RECV (_PR_MD_RECV) 258 #define _MD_SEND (_PR_MD_SEND) 259 260 /* --- Scheduler stuff --- */ 261 /* #define _MD_PAUSE_CPU _PR_MD_PAUSE_CPU */ 262 #define _MD_PAUSE_CPU 263 264 /* --- DIR stuff --- */ 265 #define PR_DIRECTORY_SEPARATOR '\\' 266 #define PR_DIRECTORY_SEPARATOR_STR "\\" 267 #define PR_PATH_SEPARATOR ';' 268 #define PR_PATH_SEPARATOR_STR ";" 269 #define _MD_ERRNO() errno 270 #define _MD_OPEN_DIR (_PR_MD_OPEN_DIR) 271 #define _MD_CLOSE_DIR (_PR_MD_CLOSE_DIR) 272 #define _MD_READ_DIR (_PR_MD_READ_DIR) 273 274 /* --- Segment stuff --- */ 275 #define _MD_INIT_SEGS() 276 #define _MD_ALLOC_SEGMENT(seg, size, vaddr) 0 277 #define _MD_FREE_SEGMENT(seg) 278 279 /* --- Environment Stuff --- */ 280 #define _MD_GET_ENV (_PR_MD_GET_ENV) 281 #define _MD_PUT_ENV (_PR_MD_PUT_ENV) 282 283 /* --- Threading Stuff --- */ 284 #define _MD_DEFAULT_STACK_SIZE 65536L 285 #define _MD_INIT_THREAD (_PR_MD_INIT_THREAD) 286 #define _MD_INIT_ATTACHED_THREAD (_PR_MD_INIT_THREAD) 287 #define _MD_CREATE_THREAD (_PR_MD_CREATE_THREAD) 288 #define _MD_YIELD (_PR_MD_YIELD) 289 #define _MD_SET_PRIORITY (_PR_MD_SET_PRIORITY) 290 #define _MD_CLEAN_THREAD (_PR_MD_CLEAN_THREAD) 291 #define _MD_SETTHREADAFFINITYMASK (_PR_MD_SETTHREADAFFINITYMASK) 292 #define _MD_GETTHREADAFFINITYMASK (_PR_MD_GETTHREADAFFINITYMASK) 293 #define _MD_EXIT_THREAD (_PR_MD_EXIT_THREAD) 294 #define _MD_SUSPEND_THREAD (_PR_MD_SUSPEND_THREAD) 295 #define _MD_RESUME_THREAD (_PR_MD_RESUME_THREAD) 296 #define _MD_SUSPEND_CPU (_PR_MD_SUSPEND_CPU) 297 #define _MD_RESUME_CPU (_PR_MD_RESUME_CPU) 298 #define _MD_WAKEUP_CPUS (_PR_MD_WAKEUP_CPUS) 299 #define _MD_BEGIN_SUSPEND_ALL() 300 #define _MD_BEGIN_RESUME_ALL() 301 #define _MD_END_SUSPEND_ALL() 302 #define _MD_END_RESUME_ALL() 303 304 /* --- Lock stuff --- */ 305 #define _PR_LOCK _MD_LOCK 306 #define _PR_UNLOCK _MD_UNLOCK 307 308 #define _MD_NEW_LOCK (_PR_MD_NEW_LOCK) 309 #define _MD_FREE_LOCK(lock) (DosCloseMutexSem((lock)->mutex)) 310 #define _MD_LOCK(lock) (DosRequestMutexSem((lock)->mutex, SEM_INDEFINITE_WAIT)) 311 #define _MD_TEST_AND_LOCK(lock) (DosRequestMutexSem((lock)->mutex, SEM_INDEFINITE_WAIT),0) 312 #define _MD_UNLOCK (_PR_MD_UNLOCK) 313 314 /* --- lock and cv waiting --- */ 315 #define _MD_WAIT (_PR_MD_WAIT) 316 #define _MD_WAKEUP_WAITER (_PR_MD_WAKEUP_WAITER) 317 318 /* --- CVar ------------------- */ 319 #define _MD_WAIT_CV (_PR_MD_WAIT_CV) 320 #define _MD_NEW_CV (_PR_MD_NEW_CV) 321 #define _MD_FREE_CV (_PR_MD_FREE_CV) 322 #define _MD_NOTIFY_CV (_PR_MD_NOTIFY_CV ) 323 #define _MD_NOTIFYALL_CV (_PR_MD_NOTIFYALL_CV) 324 325 /* XXXMB- the IOQ stuff is certainly not working correctly yet. */ 326 /* extern struct _MDLock _pr_ioq_lock; */ 327 #define _MD_IOQ_LOCK() 328 #define _MD_IOQ_UNLOCK() 329 330 331 /* --- Initialization stuff --- */ 332 #define _MD_START_INTERRUPTS() 333 #define _MD_STOP_INTERRUPTS() 334 #define _MD_DISABLE_CLOCK_INTERRUPTS() 335 #define _MD_ENABLE_CLOCK_INTERRUPTS() 336 #define _MD_BLOCK_CLOCK_INTERRUPTS() 337 #define _MD_UNBLOCK_CLOCK_INTERRUPTS() 338 #define _MD_EARLY_INIT (_PR_MD_EARLY_INIT) 339 #define _MD_FINAL_INIT() 340 #define _MD_EARLY_CLEANUP() 341 #define _MD_INIT_CPUS() 342 #define _MD_INIT_RUNNING_CPU(cpu) 343 344 struct PRProcess; 345 struct PRProcessAttr; 346 347 #define _MD_CREATE_PROCESS _PR_CreateOS2Process 348 extern struct PRProcess * _PR_CreateOS2Process( 349 const char *path, 350 char *const *argv, 351 char *const *envp, 352 const struct PRProcessAttr *attr 353 ); 354 355 #define _MD_DETACH_PROCESS _PR_DetachOS2Process 356 extern PRStatus _PR_DetachOS2Process(struct PRProcess *process); 357 358 /* --- Wait for a child process to terminate --- */ 359 #define _MD_WAIT_PROCESS _PR_WaitOS2Process 360 extern PRStatus _PR_WaitOS2Process(struct PRProcess *process, 361 PRInt32 *exitCode); 362 363 #define _MD_KILL_PROCESS _PR_KillOS2Process 364 extern PRStatus _PR_KillOS2Process(struct PRProcess *process); 365 366 #define _MD_CLEANUP_BEFORE_EXIT() 367 #define _MD_EXIT (_PR_MD_EXIT) 368 #define _MD_INIT_CONTEXT(_thread, _sp, _main, status) \ 369 PR_BEGIN_MACRO \ 370 *status = PR_TRUE; \ 371 PR_END_MACRO 372 #define _MD_SWITCH_CONTEXT 373 #define _MD_RESTORE_CONTEXT 374 375 /* --- Intervals --- */ 376 #define _MD_INTERVAL_INIT (_PR_MD_INTERVAL_INIT) 377 #define _MD_GET_INTERVAL (_PR_MD_GET_INTERVAL) 378 #define _MD_INTERVAL_PER_SEC (_PR_MD_INTERVAL_PER_SEC) 379 #define _MD_INTERVAL_PER_MILLISEC() (_PR_MD_INTERVAL_PER_SEC() / 1000) 380 #define _MD_INTERVAL_PER_MICROSEC() (_PR_MD_INTERVAL_PER_SEC() / 1000000) 381 382 /* --- Native-Thread Specific Definitions ------------------------------- */ 383 384 typedef struct __NSPR_TLS 385 { 386 struct PRThread *_pr_thread_last_run; 387 struct PRThread *_pr_currentThread; 388 struct _PRCPU *_pr_currentCPU; 389 } _NSPR_TLS; 390 391 extern _NSPR_TLS* pThreadLocalStorage; 392 NSPR_API(void) _PR_MD_ENSURE_TLS(void); 393 394 #define _MD_GET_ATTACHED_THREAD() pThreadLocalStorage->_pr_currentThread 395 extern struct PRThread * _MD_CURRENT_THREAD(void); 396 #define _MD_SET_CURRENT_THREAD(_thread) _PR_MD_ENSURE_TLS(); pThreadLocalStorage->_pr_currentThread = (_thread) 397 398 #define _MD_LAST_THREAD() pThreadLocalStorage->_pr_thread_last_run 399 #define _MD_SET_LAST_THREAD(_thread) _PR_MD_ENSURE_TLS(); pThreadLocalStorage->_pr_thread_last_run = (_thread) 400 401 #define _MD_CURRENT_CPU() pThreadLocalStorage->_pr_currentCPU 402 #define _MD_SET_CURRENT_CPU(_cpu) _PR_MD_ENSURE_TLS(); pThreadLocalStorage->_pr_currentCPU = (_cpu) 403 404 /* lth. #define _MD_SET_INTSOFF(_val) (_pr_ints_off = (_val)) */ 405 /* lth. #define _MD_GET_INTSOFF() _pr_ints_off */ 406 /* lth. #define _MD_INCREMENT_INTSOFF() (_pr_ints_off++) */ 407 /* lth. #define _MD_DECREMENT_INTSOFF() (_pr_ints_off--) */ 408 409 /* --- Scheduler stuff --- */ 410 #define LOCK_SCHEDULER() 0 411 #define UNLOCK_SCHEDULER() 0 412 #define _PR_LockSched() 0 413 #define _PR_UnlockSched() 0 414 415 /* --- Initialization stuff --- */ 416 #define _MD_INIT_LOCKS() 417 418 /* --- Stack stuff --- */ 419 #define _MD_INIT_STACK(stack, redzone) 420 #define _MD_CLEAR_STACK(stack) 421 422 /* --- Memory-mapped files stuff --- */ 423 /* ReadOnly and WriteCopy modes are simulated on OS/2; 424 * ReadWrite mode is not supported. 425 */ 426 struct _MDFileMap { 427 PROffset64 maxExtent; 428 }; 429 430 extern PRStatus _MD_CreateFileMap(struct PRFileMap *fmap, PRInt64 size); 431 #define _MD_CREATE_FILE_MAP _MD_CreateFileMap 432 433 extern PRInt32 _MD_GetMemMapAlignment(void); 434 #define _MD_GET_MEM_MAP_ALIGNMENT _MD_GetMemMapAlignment 435 436 extern void * _MD_MemMap(struct PRFileMap *fmap, PRInt64 offset, 437 PRUint32 len); 438 #define _MD_MEM_MAP _MD_MemMap 439 440 extern PRStatus _MD_MemUnmap(void *addr, PRUint32 size); 441 #define _MD_MEM_UNMAP _MD_MemUnmap 442 443 extern PRStatus _MD_CloseFileMap(struct PRFileMap *fmap); 444 #define _MD_CLOSE_FILE_MAP _MD_CloseFileMap 445 446 /* Some stuff for setting up thread contexts */ 447 typedef ULONG DWORD, *PDWORD; 448 449 /* The following definitions and two structures are new in OS/2 Warp 4.0. 450 */ 451 #ifndef CONTEXT_CONTROL 452 #define CONTEXT_CONTROL 0x00000001 453 #define CONTEXT_INTEGER 0x00000002 454 #define CONTEXT_SEGMENTS 0x00000004 455 #define CONTEXT_FLOATING_POINT 0x00000008 456 #define CONTEXT_FULL 0x0000000F 457 458 #pragma pack(2) 459 typedef struct _FPREG { 460 ULONG losig; /* Low 32-bits of the significand. */ 461 ULONG hisig; /* High 32-bits of the significand. */ 462 USHORT signexp; /* Sign and exponent. */ 463 } FPREG; 464 typedef struct _CONTEXTRECORD { 465 ULONG ContextFlags; 466 ULONG ctx_env[7]; 467 FPREG ctx_stack[8]; 468 ULONG ctx_SegGs; /* GS register. */ 469 ULONG ctx_SegFs; /* FS register. */ 470 ULONG ctx_SegEs; /* ES register. */ 471 ULONG ctx_SegDs; /* DS register. */ 472 ULONG ctx_RegEdi; /* EDI register. */ 473 ULONG ctx_RegEsi; /* ESI register. */ 474 ULONG ctx_RegEax; /* EAX register. */ 475 ULONG ctx_RegEbx; /* EBX register. */ 476 ULONG ctx_RegEcx; /* ECX register. */ 477 ULONG ctx_RegEdx; /* EDX register. */ 478 ULONG ctx_RegEbp; /* EBP register. */ 479 ULONG ctx_RegEip; /* EIP register. */ 480 ULONG ctx_SegCs; /* CS register. */ 481 ULONG ctx_EFlags; /* EFLAGS register. */ 482 ULONG ctx_RegEsp; /* ESP register. */ 483 ULONG ctx_SegSs; /* SS register. */ 484 } CONTEXTRECORD, *PCONTEXTRECORD; 485 #pragma pack() 486 #endif 487 488 extern APIRET (* APIENTRY QueryThreadContext)(TID, ULONG, PCONTEXTRECORD); 489 490 /* 491 #define _pr_tid (((PTIB2)_getTIBvalue(offsetof(TIB, tib_ptib2)))->tib2_ultid) 492 #define _pr_current_Thread (_system_tls[_pr_tid-1].__pr_current_thread) 493 */ 494 495 /* Some simple mappings of Windows API's to OS/2 API's to make our lives a 496 * little bit easier. Only add one here if it is a DIRECT mapping. We are 497 * not emulating anything. Just mapping. 498 */ 499 #define FreeLibrary(x) DosFreeModule((HMODULE)x) 500 #define OutputDebugStringA(x) 501 502 extern int _MD_os2_get_nonblocking_connect_error(int osfd); 503 504 #endif /* nspr_os2_defs_h___ */ 505