Home | History | Annotate | Download | only in md
      1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /*
      3  * The contents of this file are subject to the Mozilla Public
      4  * License Version 1.1 (the "License"); you may not use this file
      5  * except in compliance with the License. You may obtain a copy of
      6  * the License at http://www.mozilla.org/MPL/
      7  *
      8  * Software distributed under the License is distributed on an "AS
      9  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
     10  * implied. See the License for the specific language governing
     11  * rights and limitations under the License.
     12  *
     13  * The Original Code is the Netscape Portable Runtime (NSPR).
     14  *
     15  * The Initial Developer of the Original Code is Netscape
     16  * Communications Corporation.  Portions created by Netscape are
     17  * Copyright (C) 1998-2000 Netscape Communications Corporation.  All
     18  * Rights Reserved.
     19  *
     20  * Contributor(s):
     21  *
     22  * Alternatively, the contents of this file may be used under the
     23  * terms of the GNU General Public License Version 2 or later (the
     24  * "GPL"), in which case the provisions of the GPL are applicable
     25  * instead of those above.  If you wish to allow use of your
     26  * version of this file only under the terms of the GPL and not to
     27  * allow others to use your version of this file under the MPL,
     28  * indicate your decision by deleting the provisions above and
     29  * replace them with the notice and other provisions required by
     30  * the GPL.  If you do not delete the provisions above, a recipient
     31  * may use your version of this file under either the MPL or the
     32  * GPL.
     33  */
     34 
     35 #ifndef prunixos_h___
     36 #define prunixos_h___
     37 
     38 /*
     39  * If FD_SETSIZE is not defined on the command line, set the default value
     40  * before include select.h
     41  */
     42 /*
     43  * Linux: FD_SETSIZE is defined in /usr/include/sys/select.h and should
     44  * not be redefined.
     45  */
     46 #if !defined(LINUX) && !defined(DARWIN) && !defined(NEXTSTEP)
     47 #ifndef FD_SETSIZE
     48 #define FD_SETSIZE  4096
     49 #endif
     50 #endif
     51 
     52 #include <unistd.h>
     53 #include <stddef.h>
     54 #include <sys/stat.h>
     55 #include <dirent.h>
     56 #include <errno.h>
     57 
     58 #include "prio.h"
     59 #include "prmem.h"
     60 #include "prclist.h"
     61 
     62 /*
     63  * For select(), fd_set, and struct timeval.
     64  *
     65  * In The Single UNIX(R) Specification, Version 2,
     66  * the header file for select() is <sys/time.h>.
     67  *
     68  * fd_set is defined in <sys/types.h>.  Usually
     69  * <sys/time.h> includes <sys/types.h>, but on some
     70  * older systems <sys/time.h> does not include
     71  * <sys/types.h>, so we include it explicitly.
     72  */
     73 #include <sys/time.h>
     74 #include <sys/types.h>
     75 #if defined(AIX)  /* Only pre-4.2 AIX needs it, but for simplicity... */
     76 #include <sys/select.h>
     77 #endif
     78 
     79 #define PR_DIRECTORY_SEPARATOR		'/'
     80 #define PR_DIRECTORY_SEPARATOR_STR	"/"
     81 #define PR_PATH_SEPARATOR		':'
     82 #define PR_PATH_SEPARATOR_STR		":"
     83 #define GCPTR
     84 typedef int (*FARPROC)();
     85 
     86 /*
     87  * intervals at which GLOBAL threads wakeup to check for pending interrupt
     88  */
     89 #define _PR_INTERRUPT_CHECK_INTERVAL_SECS 5
     90 extern PRIntervalTime intr_timeout_ticks;
     91 
     92 /*
     93  * The bit flags for the in_flags and out_flags fields
     94  * of _PR_UnixPollDesc
     95  */
     96 #ifdef _PR_USE_POLL
     97 #define _PR_UNIX_POLL_READ    POLLIN
     98 #define _PR_UNIX_POLL_WRITE   POLLOUT
     99 #define _PR_UNIX_POLL_EXCEPT  POLLPRI
    100 #define _PR_UNIX_POLL_ERR     POLLERR
    101 #define _PR_UNIX_POLL_NVAL    POLLNVAL
    102 #define _PR_UNIX_POLL_HUP     POLLHUP
    103 #else /* _PR_USE_POLL */
    104 #define _PR_UNIX_POLL_READ    0x1
    105 #define _PR_UNIX_POLL_WRITE   0x2
    106 #define _PR_UNIX_POLL_EXCEPT  0x4
    107 #define _PR_UNIX_POLL_ERR     0x8
    108 #define _PR_UNIX_POLL_NVAL    0x10
    109 #define _PR_UNIX_POLL_HUP     0x20
    110 #endif /* _PR_USE_POLL */
    111 
    112 typedef struct _PRUnixPollDesc {
    113 	PRInt32 osfd;
    114 	PRInt16 in_flags;
    115 	PRInt16 out_flags;
    116 } _PRUnixPollDesc;
    117 
    118 typedef struct PRPollQueue {
    119     PRCList links;        /* for linking PRPollQueue's together */
    120     _PRUnixPollDesc *pds;        /* array of poll descriptors */
    121     PRUintn npds;            /* length of the array */
    122     PRPackedBool on_ioq;    /* is this on the async i/o work q? */
    123     PRIntervalTime timeout;        /* timeout, in ticks */
    124     struct PRThread *thr;
    125 } PRPollQueue;
    126 
    127 #define _PR_POLLQUEUE_PTR(_qp) \
    128     ((PRPollQueue*) ((char*) (_qp) - offsetof(PRPollQueue,links)))
    129 
    130 
    131 extern PRInt32 _PR_WaitForMultipleFDs(
    132     _PRUnixPollDesc *unixpds,
    133     PRInt32 pdcnt,
    134     PRIntervalTime timeout);
    135 extern void _PR_Unblock_IO_Wait(struct PRThread *thr);
    136 
    137 #if defined(_PR_LOCAL_THREADS_ONLY) || defined(_PR_GLOBAL_THREADS_ONLY)
    138 #define _MD_CHECK_FOR_EXIT()
    139 #endif
    140 
    141 extern fd_set _pr_md_read_set, _pr_md_write_set, _pr_md_exception_set;
    142 extern PRInt16 _pr_md_read_cnt[], _pr_md_write_cnt[], _pr_md_exception_cnt[];
    143 extern PRInt32 _pr_md_ioq_max_osfd;
    144 extern PRUint32 _pr_md_ioq_timeout;
    145 
    146 struct _MDFileDesc {
    147     int osfd;
    148 #if defined(LINUX) && defined(_PR_PTHREADS)
    149     int tcp_nodelay;  /* used by pt_LinuxSendFile */
    150 #endif
    151 };
    152 
    153 struct _MDDir {
    154 	DIR *d;
    155 };
    156 
    157 struct _PRCPU;
    158 extern void _MD_unix_init_running_cpu(struct _PRCPU *cpu);
    159 
    160 /*
    161 ** Make a redzone at both ends of the stack segment. Disallow access
    162 ** to those pages of memory. It's ok if the mprotect call's don't
    163 ** work - it just means that we don't really have a functional
    164 ** redzone.
    165 */
    166 #include <sys/mman.h>
    167 #ifndef PROT_NONE
    168 #define PROT_NONE 0x0
    169 #endif
    170 
    171 #if defined(DEBUG) && !defined(DARWIN) && !defined(NEXTSTEP)
    172 #if !defined(SOLARIS)
    173 #include <string.h>  /* for memset() */
    174 #define _MD_INIT_STACK(ts,REDZONE)					\
    175     PR_BEGIN_MACRO                 					\
    176 	(void) mprotect((void*)ts->seg->vaddr, REDZONE, PROT_NONE);	\
    177 	(void) mprotect((void*) ((char*)ts->seg->vaddr + REDZONE + ts->stackSize),\
    178 			REDZONE, PROT_NONE);				\
    179     /*									\
    180     ** Fill stack memory with something that turns into an illegal	\
    181     ** pointer value. This will sometimes find runtime references to	\
    182     ** uninitialized pointers. We don't do this for solaris because we	\
    183     ** can use purify instead.						\
    184     */									\
    185     if (_pr_debugStacks) {						\
    186 	memset(ts->allocBase + REDZONE, 0xf7, ts->stackSize);		\
    187     }									\
    188     PR_END_MACRO
    189 #else	/* !SOLARIS	*/
    190 #define _MD_INIT_STACK(ts,REDZONE)					\
    191     PR_BEGIN_MACRO                 					\
    192 	(void) mprotect((void*)ts->seg->vaddr, REDZONE, PROT_NONE);	\
    193 	(void) mprotect((void*) ((char*)ts->seg->vaddr + REDZONE + ts->stackSize),\
    194 			REDZONE, PROT_NONE);				\
    195     PR_END_MACRO
    196 #endif	/* !SOLARIS	*/
    197 
    198 /*
    199  * _MD_CLEAR_STACK
    200  *	Allow access to the redzone pages; the access was turned off in
    201  *	_MD_INIT_STACK.
    202  */
    203 #define _MD_CLEAR_STACK(ts)						\
    204     PR_BEGIN_MACRO                 					\
    205 	(void) mprotect((void*)ts->seg->vaddr, REDZONE, PROT_READ|PROT_WRITE);\
    206 	(void) mprotect((void*) ((char*)ts->seg->vaddr + REDZONE + ts->stackSize),\
    207 			REDZONE, PROT_READ|PROT_WRITE);			\
    208     PR_END_MACRO
    209 
    210 #else	/* DEBUG */
    211 
    212 #define _MD_INIT_STACK(ts,REDZONE)
    213 #define _MD_CLEAR_STACK(ts)
    214 
    215 #endif	/* DEBUG */
    216 
    217 #if !defined(SOLARIS)
    218 
    219 #define PR_SET_INTSOFF(newval)
    220 
    221 #endif
    222 
    223 /************************************************************************/
    224 
    225 extern void _PR_UnixInit(void);
    226 
    227 /************************************************************************/
    228 
    229 struct _MDProcess {
    230     pid_t pid;
    231 };
    232 
    233 struct PRProcess;
    234 struct PRProcessAttr;
    235 
    236 /* Create a new process (fork() + exec()) */
    237 #define _MD_CREATE_PROCESS _MD_CreateUnixProcess
    238 extern struct PRProcess * _MD_CreateUnixProcess(
    239     const char *path,
    240     char *const *argv,
    241     char *const *envp,
    242     const struct PRProcessAttr *attr
    243 );
    244 
    245 #define _MD_DETACH_PROCESS _MD_DetachUnixProcess
    246 extern PRStatus _MD_DetachUnixProcess(struct PRProcess *process);
    247 
    248 /* Wait for a child process to terminate */
    249 #define _MD_WAIT_PROCESS _MD_WaitUnixProcess
    250 extern PRStatus _MD_WaitUnixProcess(struct PRProcess *process,
    251     PRInt32 *exitCode);
    252 
    253 #define _MD_KILL_PROCESS _MD_KillUnixProcess
    254 extern PRStatus _MD_KillUnixProcess(struct PRProcess *process);
    255 
    256 /************************************************************************/
    257 
    258 extern void _MD_EnableClockInterrupts(void);
    259 extern void _MD_DisableClockInterrupts(void);
    260 
    261 #define _MD_START_INTERRUPTS			_MD_StartInterrupts
    262 #define _MD_STOP_INTERRUPTS				_MD_StopInterrupts
    263 #define _MD_DISABLE_CLOCK_INTERRUPTS	_MD_DisableClockInterrupts
    264 #define _MD_ENABLE_CLOCK_INTERRUPTS		_MD_EnableClockInterrupts
    265 #define _MD_BLOCK_CLOCK_INTERRUPTS		_MD_BlockClockInterrupts
    266 #define _MD_UNBLOCK_CLOCK_INTERRUPTS	_MD_UnblockClockInterrupts
    267 
    268 /************************************************************************/
    269 
    270 extern void		_MD_InitCPUS(void);
    271 #define _MD_INIT_CPUS           _MD_InitCPUS
    272 
    273 extern void		_MD_Wakeup_CPUs(void);
    274 #define _MD_WAKEUP_CPUS _MD_Wakeup_CPUs
    275 
    276 #define _MD_PAUSE_CPU			_MD_PauseCPU
    277 
    278 #if defined(_PR_LOCAL_THREADS_ONLY) || defined(_PR_GLOBAL_THREADS_ONLY)
    279 #define _MD_CLEANUP_BEFORE_EXIT()
    280 #endif
    281 
    282 #ifndef IRIX
    283 #define _MD_EXIT(status)		_exit(status)
    284 #endif
    285 
    286 /************************************************************************/
    287 
    288 #define _MD_GET_ENV				getenv
    289 #define _MD_PUT_ENV				putenv
    290 
    291 /************************************************************************/
    292 
    293 #define _MD_INIT_FILEDESC(fd)
    294 
    295 extern void		_MD_MakeNonblock(PRFileDesc *fd);
    296 #define _MD_MAKE_NONBLOCK			_MD_MakeNonblock
    297 
    298 /************************************************************************/
    299 
    300 #if !defined(_PR_PTHREADS)
    301 
    302 extern void		_MD_InitSegs(void);
    303 extern PRStatus	_MD_AllocSegment(PRSegment *seg, PRUint32 size,
    304 				void *vaddr);
    305 extern void		_MD_FreeSegment(PRSegment *seg);
    306 
    307 #define _MD_INIT_SEGS			_MD_InitSegs
    308 #define _MD_ALLOC_SEGMENT		_MD_AllocSegment
    309 #define _MD_FREE_SEGMENT		_MD_FreeSegment
    310 
    311 #endif /* !defined(_PR_PTHREADS) */
    312 
    313 /************************************************************************/
    314 
    315 #if !defined(HPUX_LW_TIMER)
    316 #define _MD_INTERVAL_INIT()
    317 #endif
    318 #define _MD_INTERVAL_PER_MILLISEC()	(_PR_MD_INTERVAL_PER_SEC() / 1000)
    319 #define _MD_INTERVAL_PER_MICROSEC()	(_PR_MD_INTERVAL_PER_SEC() / 1000000)
    320 
    321 /************************************************************************/
    322 
    323 #define _MD_ERRNO()             	(errno)
    324 #define _MD_GET_SOCKET_ERROR()		(errno)
    325 
    326 /************************************************************************/
    327 
    328 extern PRInt32 _MD_AvailableSocket(PRInt32 osfd);
    329 
    330 extern void _MD_StartInterrupts(void);
    331 extern void _MD_StopInterrupts(void);
    332 extern void _MD_DisableClockInterrupts(void);
    333 extern void _MD_BlockClockInterrupts(void);
    334 extern void _MD_UnblockClockInterrupts(void);
    335 extern void _MD_PauseCPU(PRIntervalTime timeout);
    336 
    337 extern PRStatus _MD_open_dir(struct _MDDir *, const char *);
    338 extern PRInt32  _MD_close_dir(struct _MDDir *);
    339 extern char *   _MD_read_dir(struct _MDDir *, PRIntn);
    340 extern PRInt32  _MD_open(const char *name, PRIntn osflags, PRIntn mode);
    341 extern PRInt32	_MD_delete(const char *name);
    342 extern PRInt32	_MD_getfileinfo(const char *fn, PRFileInfo *info);
    343 extern PRInt32  _MD_getfileinfo64(const char *fn, PRFileInfo64 *info);
    344 extern PRInt32  _MD_getopenfileinfo(const PRFileDesc *fd, PRFileInfo *info);
    345 extern PRInt32  _MD_getopenfileinfo64(const PRFileDesc *fd, PRFileInfo64 *info);
    346 extern PRInt32	_MD_rename(const char *from, const char *to);
    347 extern PRInt32	_MD_access(const char *name, PRAccessHow how);
    348 extern PRInt32	_MD_mkdir(const char *name, PRIntn mode);
    349 extern PRInt32	_MD_rmdir(const char *name);
    350 extern PRInt32	_MD_accept_read(PRInt32 sock, PRInt32 *newSock,
    351 				PRNetAddr **raddr, void *buf, PRInt32 amount);
    352 extern PRInt32 	_PR_UnixSendFile(PRFileDesc *sd, PRSendFileData *sfd,
    353 			PRTransmitFileFlags flags, PRIntervalTime timeout);
    354 
    355 extern PRStatus _MD_LockFile(PRInt32 osfd);
    356 extern PRStatus _MD_TLockFile(PRInt32 osfd);
    357 extern PRStatus _MD_UnlockFile(PRInt32 osfd);
    358 
    359 #define _MD_OPEN_DIR(dir, name)		    _MD_open_dir(dir, name)
    360 #define _MD_CLOSE_DIR(dir)		        _MD_close_dir(dir)
    361 #define _MD_READ_DIR(dir, flags)	    _MD_read_dir(dir, flags)
    362 #define _MD_OPEN(name, osflags, mode)	_MD_open(name, osflags, mode)
    363 #define _MD_OPEN_FILE(name, osflags, mode)	_MD_open(name, osflags, mode)
    364 extern PRInt32 _MD_read(PRFileDesc *fd, void *buf, PRInt32 amount);
    365 #define _MD_READ(fd,buf,amount)		    _MD_read(fd,buf,amount)
    366 extern PRInt32 _MD_write(PRFileDesc *fd, const void *buf, PRInt32 amount);
    367 #define _MD_WRITE(fd,buf,amount)	    _MD_write(fd,buf,amount)
    368 #define _MD_DELETE(name)		        _MD_delete(name)
    369 #define _MD_GETFILEINFO(fn, info)	    _MD_getfileinfo(fn, info)
    370 #define _MD_GETFILEINFO64(fn, info)	    _MD_getfileinfo64(fn, info)
    371 #define _MD_GETOPENFILEINFO(fd, info)	_MD_getopenfileinfo(fd, info)
    372 #define _MD_GETOPENFILEINFO64(fd, info)	_MD_getopenfileinfo64(fd, info)
    373 #define _MD_RENAME(from, to)		    _MD_rename(from, to)
    374 #define _MD_ACCESS(name, how)		    _MD_access(name, how)
    375 #define _MD_MKDIR(name, mode)		    _MD_mkdir(name, mode)
    376 #define _MD_MAKE_DIR(name, mode)		_MD_mkdir(name, mode)
    377 #define _MD_RMDIR(name)			        _MD_rmdir(name)
    378 #define _MD_ACCEPT_READ(sock, newSock, raddr, buf, amount)	_MD_accept_read(sock, newSock, raddr, buf, amount)
    379 
    380 #define _MD_LOCKFILE _MD_LockFile
    381 #define _MD_TLOCKFILE _MD_TLockFile
    382 #define _MD_UNLOCKFILE _MD_UnlockFile
    383 
    384 
    385 extern PRInt32		_MD_socket(int af, int type, int flags);
    386 #define _MD_SOCKET	_MD_socket
    387 extern PRInt32		_MD_connect(PRFileDesc *fd, const PRNetAddr *addr,
    388 								PRUint32 addrlen, PRIntervalTime timeout);
    389 #define _MD_CONNECT	_MD_connect
    390 extern PRInt32		_MD_accept(PRFileDesc *fd, PRNetAddr *addr, PRUint32 *addrlen,
    391 													PRIntervalTime timeout);
    392 #define _MD_ACCEPT	_MD_accept
    393 extern PRInt32		_MD_bind(PRFileDesc *fd, const PRNetAddr *addr, PRUint32 addrlen);
    394 #define _MD_BIND	_MD_bind
    395 extern PRInt32		_MD_listen(PRFileDesc *fd, PRIntn backlog);
    396 #define _MD_LISTEN	_MD_listen
    397 extern PRInt32		_MD_shutdown(PRFileDesc *fd, PRIntn how);
    398 #define _MD_SHUTDOWN	_MD_shutdown
    399 
    400 extern PRInt32		_MD_recv(PRFileDesc *fd, void *buf, PRInt32 amount,
    401                                PRIntn flags, PRIntervalTime timeout);
    402 #define _MD_RECV	_MD_recv
    403 extern PRInt32		_MD_send(PRFileDesc *fd, const void *buf, PRInt32 amount,
    404 									PRIntn flags, PRIntervalTime timeout);
    405 #define _MD_SEND	_MD_send
    406 extern PRInt32		_MD_recvfrom(PRFileDesc *fd, void *buf, PRInt32 amount,
    407 						PRIntn flags, PRNetAddr *addr, PRUint32 *addrlen,
    408 											PRIntervalTime timeout);
    409 #define _MD_RECVFROM	_MD_recvfrom
    410 extern PRInt32 _MD_sendto(PRFileDesc *fd, const void *buf, PRInt32 amount,
    411 							PRIntn flags, const PRNetAddr *addr, PRUint32 addrlen,
    412 												PRIntervalTime timeout);
    413 #define _MD_SENDTO	_MD_sendto
    414 extern PRInt32		_MD_writev(PRFileDesc *fd, const struct PRIOVec *iov,
    415 								PRInt32 iov_size, PRIntervalTime timeout);
    416 #define _MD_WRITEV	_MD_writev
    417 
    418 extern PRInt32		_MD_socketavailable(PRFileDesc *fd);
    419 #define	_MD_SOCKETAVAILABLE		_MD_socketavailable
    420 extern PRInt64		_MD_socketavailable64(PRFileDesc *fd);
    421 #define	_MD_SOCKETAVAILABLE64		_MD_socketavailable64
    422 
    423 #define	_MD_PIPEAVAILABLE		_MD_socketavailable
    424 
    425 extern PRInt32 _MD_pr_poll(PRPollDesc *pds, PRIntn npds,
    426 												PRIntervalTime timeout);
    427 #define _MD_PR_POLL		_MD_pr_poll
    428 
    429 extern PRInt32		_MD_close(PRInt32 osfd);
    430 #define _MD_CLOSE_FILE	_MD_close
    431 extern PRInt32		_MD_lseek(PRFileDesc*, PRInt32, PRSeekWhence);
    432 #define _MD_LSEEK	_MD_lseek
    433 extern PRInt64		_MD_lseek64(PRFileDesc*, PRInt64, PRSeekWhence);
    434 #define _MD_LSEEK64	_MD_lseek64
    435 extern PRInt32		_MD_fsync(PRFileDesc *fd);
    436 #define _MD_FSYNC	_MD_fsync
    437 
    438 extern PRInt32 _MD_socketpair(int af, int type, int flags, PRInt32 *osfd);
    439 #define _MD_SOCKETPAIR		_MD_socketpair
    440 
    441 #define _MD_CLOSE_SOCKET	_MD_close
    442 
    443 #ifndef NO_NSPR_10_SUPPORT
    444 #define _MD_STAT	stat
    445 #endif
    446 
    447 extern PRStatus _MD_getpeername(PRFileDesc *fd, PRNetAddr *addr,
    448 											PRUint32 *addrlen);
    449 #define _MD_GETPEERNAME _MD_getpeername
    450 extern PRStatus _MD_getsockname(PRFileDesc *fd, PRNetAddr *addr,
    451 											PRUint32 *addrlen);
    452 #define _MD_GETSOCKNAME _MD_getsockname
    453 
    454 extern PRStatus _MD_getsockopt(PRFileDesc *fd, PRInt32 level,
    455 						PRInt32 optname, char* optval, PRInt32* optlen);
    456 #define _MD_GETSOCKOPT		_MD_getsockopt
    457 extern PRStatus _MD_setsockopt(PRFileDesc *fd, PRInt32 level,
    458 					PRInt32 optname, const char* optval, PRInt32 optlen);
    459 #define _MD_SETSOCKOPT		_MD_setsockopt
    460 
    461 extern PRStatus _MD_set_fd_inheritable(PRFileDesc *fd, PRBool inheritable);
    462 #define _MD_SET_FD_INHERITABLE _MD_set_fd_inheritable
    463 
    464 extern void _MD_init_fd_inheritable(PRFileDesc *fd, PRBool imported);
    465 #define _MD_INIT_FD_INHERITABLE _MD_init_fd_inheritable
    466 
    467 extern void _MD_query_fd_inheritable(PRFileDesc *fd);
    468 #define _MD_QUERY_FD_INHERITABLE _MD_query_fd_inheritable
    469 
    470 extern PRStatus _MD_gethostname(char *name, PRUint32 namelen);
    471 #define _MD_GETHOSTNAME		_MD_gethostname
    472 
    473 extern PRStatus _MD_getsysinfo(PRSysInfo cmd, char *name, PRUint32 namelen);
    474 #define _MD_GETSYSINFO		_MD_getsysinfo
    475 
    476 extern int _MD_unix_get_nonblocking_connect_error(int osfd);
    477 
    478 /* Memory-mapped files */
    479 
    480 struct _MDFileMap {
    481     PRIntn prot;
    482     PRIntn flags;
    483     PRBool isAnonFM; /* when true, PR_CloseFileMap() must close the related fd */
    484 };
    485 
    486 extern PRStatus _MD_CreateFileMap(struct PRFileMap *fmap, PRInt64 size);
    487 #define _MD_CREATE_FILE_MAP _MD_CreateFileMap
    488 
    489 #define _MD_GET_MEM_MAP_ALIGNMENT() PR_GetPageSize()
    490 
    491 extern void * _MD_MemMap(struct PRFileMap *fmap, PRInt64 offset,
    492         PRUint32 len);
    493 #define _MD_MEM_MAP _MD_MemMap
    494 
    495 extern PRStatus _MD_MemUnmap(void *addr, PRUint32 size);
    496 #define _MD_MEM_UNMAP _MD_MemUnmap
    497 
    498 extern PRStatus _MD_CloseFileMap(struct PRFileMap *fmap);
    499 #define _MD_CLOSE_FILE_MAP _MD_CloseFileMap
    500 
    501 /*
    502  * The standard (XPG4) gettimeofday() (from BSD) takes two arguments.
    503  * On some SVR4 derivatives, gettimeofday() takes only one argument.
    504  * The GETTIMEOFDAY macro is intended to hide this difference.
    505  */
    506 #ifdef HAVE_SVID_GETTOD
    507 #define GETTIMEOFDAY(tp) gettimeofday(tp)
    508 #else
    509 #define GETTIMEOFDAY(tp) gettimeofday((tp), NULL)
    510 #endif
    511 
    512 #if defined(_PR_PTHREADS) && !defined(_PR_POLL_AVAILABLE)
    513 #define _PR_NEED_FAKE_POLL
    514 #endif
    515 
    516 #if defined(_PR_NEED_FAKE_POLL)
    517 
    518 /*
    519  * Some platforms don't have poll(), but our pthreads code calls poll().
    520  * As a temporary measure, I implemented a fake poll() using select().
    521  * Here are the struct and macro definitions copied from sys/poll.h
    522  * on Solaris 2.5.
    523  */
    524 
    525 struct pollfd {
    526     int fd;
    527     short events;
    528     short revents;
    529 };
    530 
    531 /* poll events */
    532 
    533 #define	POLLIN		0x0001		/* fd is readable */
    534 #define	POLLPRI		0x0002		/* high priority info at fd */
    535 #define	POLLOUT		0x0004		/* fd is writeable (won't block) */
    536 #define	POLLRDNORM	0x0040		/* normal data is readable */
    537 #define	POLLWRNORM	POLLOUT
    538 #define	POLLRDBAND	0x0080		/* out-of-band data is readable */
    539 #define	POLLWRBAND	0x0100		/* out-of-band data is writeable */
    540 
    541 #define	POLLNORM	POLLRDNORM
    542 
    543 #define	POLLERR		0x0008		/* fd has error condition */
    544 #define	POLLHUP		0x0010		/* fd has been hung up on */
    545 #define	POLLNVAL	0x0020		/* invalid pollfd entry */
    546 
    547 extern int poll(struct pollfd *, unsigned long, int);
    548 
    549 #endif /* _PR_NEED_FAKE_POLL */
    550 
    551 /*
    552 ** A vector of the UNIX I/O calls we use. These are here to smooth over
    553 ** the rough edges needed for large files. All of NSPR's implmentaions
    554 ** go through this vector using syntax of the form
    555 **      result = _md_iovector.xxx64(args);
    556 */
    557 
    558 #if defined(SOLARIS2_5)
    559 /*
    560 ** Special case: Solaris 2.5.1
    561 ** Solaris starts to have 64-bit file I/O in 2.6.  We build on Solaris
    562 ** 2.5.1 so that we can use the same binaries on both Solaris 2.5.1 and
    563 ** 2.6.  At run time, we detect whether 64-bit file I/O is available by
    564 ** looking up the 64-bit file function symbols in libc.  At build time,
    565 ** we need to define the 64-bit file I/O datatypes that are compatible
    566 ** with their definitions on Solaris 2.6.
    567 */
    568 typedef PRInt64 off64_t;
    569 typedef PRUint64 ino64_t;
    570 typedef PRInt64 blkcnt64_t;
    571 struct stat64 {
    572     dev_t st_dev;
    573     long st_pad1[3];
    574     ino64_t st_ino;
    575     mode_t st_mode;
    576     nlink_t st_nlink;
    577     uid_t st_uid;
    578     gid_t st_gid;
    579     dev_t st_rdev;
    580     long t_pad2[2];
    581     off64_t st_size;
    582     timestruc_t st_atim;
    583     timestruc_t st_mtim;
    584     timestruc_t st_ctim;
    585     long st_blksize;
    586     blkcnt64_t st_blocks;
    587     char st_fstype[_ST_FSTYPSZ];
    588     long st_pad4[8];
    589 };
    590 typedef struct stat64 _MDStat64;
    591 typedef off64_t _MDOff64_t;
    592 
    593 #elif defined(_PR_HAVE_OFF64_T)
    594 typedef struct stat64 _MDStat64;
    595 typedef off64_t _MDOff64_t;
    596 #elif defined(_PR_HAVE_LARGE_OFF_T)
    597 typedef struct stat _MDStat64;
    598 typedef off_t _MDOff64_t;
    599 #elif defined(_PR_NO_LARGE_FILES)
    600 typedef struct stat _MDStat64;
    601 typedef PRInt64 _MDOff64_t;
    602 #else
    603 #error "I don't know yet"
    604 #endif
    605 
    606 typedef PRIntn (*_MD_Fstat64)(PRIntn osfd, _MDStat64 *buf);
    607 typedef PRIntn (*_MD_Open64)(const char *path, int oflag, ...);
    608 #if defined(VMS)
    609 typedef PRIntn (*_MD_Stat64)(const char *path, _MDStat64 *buf, ...);
    610 #else
    611 typedef PRIntn (*_MD_Stat64)(const char *path, _MDStat64 *buf);
    612 #endif
    613 typedef _MDOff64_t (*_MD_Lseek64)(PRIntn osfd, _MDOff64_t, PRIntn whence);
    614 typedef void* (*_MD_Mmap64)(
    615     void *addr, PRSize len, PRIntn prot, PRIntn flags,
    616     PRIntn fildes, _MDOff64_t offset);
    617 struct _MD_IOVector
    618 {
    619     _MD_Open64 _open64;
    620     _MD_Mmap64 _mmap64;
    621     _MD_Stat64 _stat64;
    622     _MD_Fstat64 _fstat64;
    623     _MD_Lseek64 _lseek64;
    624 };
    625 extern struct _MD_IOVector _md_iovector;
    626 
    627 #endif /* prunixos_h___ */
    628