/* begincopyright Copyright (c) 1988 Xerox Corporation. All rights reserved. Use and copying of this software and preparation of derivative works based upon this software are permitted. Any distribution of this software or derivative works must comply with all applicable United States export control laws. This software is made available AS IS, and Xerox Corporation makes no warranty about the software, its performance or its conformity to any specification. Any person obtaining a copy of this software is requested to send their name and post office or electronic mail address to: PCR Coordinator Xerox PARC 3333 Coyote Hill Rd. Palo Alto, CA 94304 endcopyright */ /* * UIOPrivate.h * * * Private definitions for Unix I/O interface * for Xerox Runtime threads package. * * Suitable for AT&T streams. * * Demers, July 30, 1990 9:53:32 am PDT * Boehm, May 14, 1990 2:51:23 pm PDT */ #ifndef _XR_UIO_PRIVATE_ #define _XR_UIO_PRIVATE_ 1 #ifndef _XR_THREADS_BACKDOOR_ # include "ThreadsBackdoor.h" #endif #ifndef _XR_UIO_ # include "UIO.h" #endif /* * The following controls whether STREAMS support is compiled in. * On some systems we may have to fudge the streams header files * if STREAMS is false. */ #define STREAMS 1 /* * The following controls a hack in ThreadsUIO.c/USysCalls.c to allow strings * declared in data or bss segments to be passed to IOPs in a packaged * threads configuration. It doesn't hurt anything in other configurations. * * NOTE: in 2_12 and later versions this is NEVER needed. */ #define XR_COPY_FOR_PACKAGED_THREADS 0 /* * Queue of events (Unix signals) passed back to PCR threads ... */ #define XR_UIO_EVENT_QUEUE_SIZE 8 /* * Max descriptors per IOP. * Each kind of UIO IOP may implement fewer than this ... */ #define XR_MAX_FDS_PER_IOP 256 #if !defined(POLLIN) # include #endif #if STREAMS # if !defined(I_STR) # include # endif #endif #if XR_COPY_FOR_PACKAGED_THREADS extern char * XR_UIOFixStringArg(); #else # define XR_UIOFixStringArg(x) (x) #endif /* * Wait Kinds -- set of descriptor events to wait for * * Taken from System V */ typedef unsigned XR_UIOWaitKinds; /* POLLIN -- normal input POLLPRI -- priority input POLLOUT -- output POLLERR -- error return POLLHUP -- stream disappeared POLLNVAL -- descriptor not a stream */ /* * State of FDE * * It's okay to `OR' XR_FDE_STATE_BUSY into any other state. */ typedef unsigned XR_FDEState; # define XR_FDE_STATE_FREE ((XR_FDEState)(0)) # define XR_FDE_STATE_BUSY ((XR_FDEState)(1)) # define XR_FDE_STATE_OPEN ((XR_FDEState)(2)) /* * Data structures for virtual file descriptor entries (FDE's) * and physical file descriptor cache entries (FDC's) */ #define XR_FDC struct XR_FDCRep * #define XR_FDE struct XR_FDERep * typedef struct XR_FDERep { int fde_index; unsigned fde_gen; /* generation number */ int fde_opCnt; /* # ops in progress */ XR_FDEState fde_state; XR_IOPE fde_owner; /* IOP that owns descriptor */ int fde_ownerIndex; /* owner's descriptor index */ XR_FDKind fde_fdKind; /* kind of associated descriptors */ /* (same as kind of IOP) */ XR_UIOBlocking fde_getBlocking; /* input blocking behavior */ XR_UIOBlocking fde_putBlocking; /* output blocking behavior */ XR_Ticks fde_getTimeout; /* input timeout */ XR_Ticks fde_putTimeout; /* output timeout */ bool fde_inputPri; /* poll input => pri */ XR_FDC fde_fdc; /* -> cached fdc or NIL */ struct XR_CVRep fde_avail; /* wait here e.g. for FDC */ #undef XR_FDE } * XR_FDE; typedef struct XR_FDCRep { int fdc_index; /* index in cache */ unsigned fdc_whenUsed; /* for LRU */ bool fdc_valid; /* Unix descriptor exists */ XR_FDE fdc_fde; /* associated fde or NIL */ #undef XR_FDC } * XR_FDC; /* * UIO IOP working directory maintenance */ typedef struct XR_UIOWDBufRep { int wdb_maxLen; int wdb_len; char wdb_data[ /*maxLen+1*/ 4]; } * XR_UIOWDBuf; #define XR_UIOWDBufBytes(len) ( sizeof(struct XR_UIOWDBufRep) + (len) - 3 ) extern char * XR_UIOFixPathForIOP(/* char *path, XR_IOPE iope */); /* (to be called only from a thread) Return (possibly new, heap-allocated) full pathname for path. As side-effect, if iope is not NIL, ensure that the IOP's wdBuf is big enough to hold (the directory prefix of) the full path name. */ extern int XR_UIOIOPChDirForPaths(/* char *fullPath, char *fullPath2 */); /* (fullPath2 may be NIL) (to be called only from IOP) Change IOP's unix working directory to appropriate (common) prefix of fullPath (and fullPath2 if it's not NIL). Store working directory in IOP's WD slot, to be accessed by XR_GetUIOIOPEWD(iope). Return length of common prefix (which is now IOP's working directory) on success, or (-errno) on failure. */ /* * * UIO system data structure * */ typedef struct XR_UIOAreaRep { /* monitor locks */ struct XR_MLRep uioa_ml; struct XR_MLRep uioa_wdML; /* PCR working directory cache */ XR_UIOWDBuf uioa_pcrWD; /* IOPs */ XR_IOPE uioa_iope; int uioa_numIOPE; # define XR_UIOIOPELimit \ (&(XR_uioArea->uioa_iope[XR_uioArea->uioa_numIOPE])) /* FDEs */ XR_FDE uioa_fde; int uioa_numFDE; # define XR_UIOFDELimit \ (&(XR_uioArea->uioa_fde[XR_uioArea->uioa_numFDE])) /* FDCs */ XR_FDC uioa_fdc; int uioa_numFDC; # define XR_UIOFDCLimit \ (&(XR_uioArea->uioa_fdc[XR_uioArea->uioa_numFDC])) /* cv for spinning to wait for free fdc (rare!) */ struct XR_CVRep uioa_spinCV; /* op count (for LRU) */ unsigned uioa_opCnt; /* misc data for sys calls */ XR_IOPOrder uioa_spawnWaitList; bool uioa_spawnChildDied; struct XR_VPOrderRep uioa_profVPOrderBuf; } * XR_UIOArea; extern XR_UIOArea XR_uioArea; /* readonly, shared */ /* * IOPE client data fields * * (uioFreeSlots is protected by uioArea monitor lock uioa_ml) * (IOPEWDBuf is protected by uioArea monitor lock uioa_wdML) */ #define iope_uioFDKind iope_clientData[0] #define iope_uioFDEBase iope_clientData[1] #define iope_uioFreeSlots iope_clientData[2] #define XR_GetUIOIOPEWD(iope) \ ((XR_UIOWDBuf)((iope)->iope_clientData[3])) #define XR_SetUIOIOPEWD(iope, wdb) \ (iope)->iope_clientData[3] = ((unsigned)(wdb)) #define XR_GetUIOIOPEWDBuf(iope) \ ((XR_UIOWDBuf)((iope)->iope_clientData[4])) #define XR_SetUIOIOPEWDBuf(iope, wdb) \ (iope)->iope_clientData[4] = ((unsigned)(wdb)) /* * * Per-IOP data structure for wait-until-ready requests * */ typedef struct XR_WaitReadyDataRep { struct pollfd wrd_pollfd; } * XR_WaitReadyData; # define wrd_fd wrd_pollfd.fd # define wrd_events wrd_pollfd.events # define wrd_revents wrd_pollfd.revents #define XR_waitReadyData ((XR_WaitReadyData)(XR_iope->iope_clientData[5])) #define XR_GetWaitReadyData(iope) \ ((XR_WaitReadyData)((iope)->iope_clientData[5])) #define XR_SetWaitReadyData(iope, d) \ (iope)->iope_clientData[5] = ((unsigned)(d)) #define XR_numWaitReadyData (XR_iope->iope_clientData[6]) #define XR_GetNumWaitReadyData(iope) \ ((iope)->iope_clientData[6]) #define XR_SetNumWaitReadyData(iope,x) \ (iope)->iope_clientData[6] = ((unsigned)(x)) typedef struct XR_WaitReadyHeaderRep { unsigned wrh_index; XR_WaitReadyData wrh_wrd; /* ref to WaitReadyDataRep or NIL */ XR_IOPOrder wrh_orders; /* list of wait ready orders for this FDE */ } * XR_WaitReadyHeader; #define XR_waitReadyHeaders ((XR_WaitReadyHeader)(XR_iope->iope_clientData[7])) #define XR_GetWaitReadyHeaders(iope) \ ((XR_WaitReadyHeader)((iope)->iope_clientData[7])) #define XR_SetWaitReadyHeaders(iope,h) \ (iope)->iope_clientData[7] = ((unsigned)(h)) /* * Asynchronous events */ typedef struct XR_UIOEventQueueRep { unsigned uioeq_wNum; unsigned uioeq_rNum; int uioeq_eventID[XR_UIO_EVENT_QUEUE_SIZE] } *XR_UIOEventQueue; #define XR_uioEventQueue ((XR_UIOEventQueue)(XR_iope->iope_clientData[8])) #define XR_GetUIOEventQueue(iope) \ ((XR_UIOEventQueue)((iope)->iope_clientData[8])) #define XR_SetUIOEventQueue(iope,q) \ (iope)->iope_clientData[8] = ((unsigned)(q)) extern void XR_UIONotifyEventAvail(); /* Notify any waiting thread of an asynchronous event in IOP. */ /* * * Descriptor Utilities * */ #define XR_IOP_POLL_TIMEOUT_MSEC 2000 /* internal timeout */ extern int XR_UIOPollStd( /* XR_waitReadyData fds, int nfds, unsigned timeout, unsigned *flagp */ ); /* Like a System V poll call, but on standard descriptors. The timeout is specified in msec. As late as possible, test *flagp and if it is nonzero, return (-1) with errno set to EINTR. Ideally this should be atomic! Normal result is number of descriptors that tested ready. */ extern bool XR_UIOPollStream( /* XR_waitReadyData fds, int nfds, unsigned timeout, unsigned *flagp */ /* Assumed to be called only from IOP, or with stack arguments. */ ); /* Like XR_UIOPollStd. */ /* * IOP order proc utilities */ extern int XR_UIOIOPFixDescriptor (/* fde, d */); /* XR_FDE fde; int d; XR_FDKind kind; Assume d is the result of a Unix system call to create a descriptor -- open, socket, ... (thus d could be -1). Insist that d be of right kind for fde, else return (-ENOSTR). Set `d' to be non-blocking, move it to the descriptor slot corresponding to `fde'. Return the new descriptor (guaranteed to be the slot corresponding to `fde', which may be different from the original value of d), or -errno on failure. On error returns, the descriptor `d' has been closed. */ extern int XR_UIOIOPSetNonBlockingStd(/*int d*/); /* Set Unix (standard) descriptor d to non-blocking. Return d on success, or (-errno) on failure. */ extern int XR_UIOIOPSetNonBlockingStream(/*int d*/); /* Set Unix (streams) descriptor d to non-blocking. Return d on success, or (-errno) on failure. */ extern void XR_UIONotifyIOPODone(/* iopo */); /* XR_IOPOrder iopo; Set iopo_done and do a naked notify of iopo_cv, with some error checking. This is the approved way to notify the waiting thread that an IOP order has been completed. */ extern unsigned XR_UIOComputeLengthForSingleIOSysCall(/* char *b, unsigned maxlen */); /* Compute length for a single I/O call, to limit amount of time spent uninterruptably blocked in system call. */ /* * * VP Orders * */ /* --- */ #define vpo_fdc vpo_args[0] extern void XR_RecvDescriptorVPOrderProc (/* vpo */); /* XR_VPOrder vpo; Receive descriptor. Argument in vpo_fdc tells where it belongs. */ extern void XR_FlushDescriptorVPOrderProc (/* vpo */); /* XR_VPOrder vpo; Flush cached descriptor. Argument in vpo_fdc tells which one. */ /* --- */ #define vpo_profBuf vpo_args[0] #define vpo_profBufSize vpo_args[1] #define vpo_profOffset vpo_args[2] #define vpo_profScale vpo_args[3] extern void XR_ProfilVPOrderProc (/* vpo */); /* XR_VPOrder vpo; Execute profil system call. */ /* --- */ #define vpo_mma vpo_args[0] extern void XR_MMapVPOrderProc (/* vpo */); /* XR_VPOrder vpo; Execute mmap system call in vp. */ extern void XR_MUnmapVPOrderProc (/* vpo */); /* XR_VPOrder vpo; Execute munmap system call in vp. */ extern void XR_MProtectVPOrderProc (/* vpo */); /* XR_VPOrder vpo; Execute mprotect system call in vp. */ /* --- */ #define vpo_sha vpo_args[0] extern void XR_ShmAtVPOrderProc (/* vpo */); /* XR_VPOrder vpo; Execute shmat system call. */ extern void XR_ShmDtVPOrderProc (/* vpo */); /* XR_VPOrder vpo; Execute shmdt system call. */ /* * * IOPOrders * */ /* * args shared by many procs */ #define iopo_fdc iopo_args[0] #define iopo_fde iopo_args[1] /* --- */ #define iopo_oName iopo_args[2] #define iopo_oFlags iopo_args[3] #define iopo_oMode iopo_args[4] extern void XR_OpenIOPOrderProc (/* iopo */); /* XR_IOPOrder iopo; Open a named file. Args in iopo_fde, iopo_oName, iopo_oFlags, iopo_oMode. Result in iopo_results[0] is (fde_ownerIndex) or (-errno). */ /* --- */ extern void XR_CloseIOPOrderProc (/* iopo */); /* XR_IOPOrder iopo; Close a descriptor. Arg in iopo_fde and fde_fdc (cache entry to flush by issuing VPOrder, may be NIL). Result in iopo_results[0] is 0 or (-errno). */ /* --- */ extern void XR_SendDescriptorIOPOrderProc (/* iopo */); /* XR_IOPOrder iopo; Send a descriptor to the VP caches. Arguments in iopo_fde (=> which descriptor) and iopo_fdc (which cache entry to store into). Assumed never to fail (panic if it does). */ /* --- */ #define iopo_wrHow iopo_args[2] extern void XR_WaitReadyIOPOrderProc (/* iopo */); /* XR_IOPOrder iopo; Args in iopo_fde and iopo_wrHow. Wait for descriptor to be ready as specified by wrHow. Result in iopo_results[0] is 0 or (-errno). */ extern void XR_WaitReadyIOPCancelProc (/* iopo */); /* XR_IOPOrder iopo; Cancel previously issued WaitReady order in iopo. */ /* --- */ #define iopo_sAf iopo_args[2] #define iopo_sType iopo_args[3] #define iopo_sProtocol iopo_args[4] extern void XR_SocketIOPOrderProc (/* iopo */); /* XR_IOPOrder iopo; Execute socket call. Result in iopo_results[0] is (fde_ownerIndex) or (-errno) */ /* --- */ #define iopo_accNewFDE iopo_args[2] #define iopo_accAddr iopo_args[3] #define iopo_accAddrLen iopo_args[4] extern void XR_AcceptIOPOrderProc (/* iopo */); /* XR_IOPOrder iopo; Execute accept call. Result in iopo_results[0] is (new fde_ownerIndex) or (-errno) */ /* --- */ #define iopo_profBuf iopo_args[0] #define iopo_profBufSize iopo_args[1] #define iopo_profOffset iopo_args[2] #define iopo_profScale iopo_args[3] extern void XR_ProfilIOPOrderProc (/* iopo */); /* XR_IOPOrder iopo; Order all VProcessors to execute profile call. */ /* --- */ #define iopo_mma iopo_args[0] extern void XR_MMapIOPOrderProc (/* iopo */); /* XR_IOPOrder iopo; Recv descriptor and do mmap call on IOP. If this is IOP 0, send mmap order to all the vprocessors. */ extern void XR_MUnmapIOPOrderProc (/* iopo */); /* XR_IOPOrder iopo; Do munmap call on IOP. If this is IOP 0, send munmap order to all the vprocessors. */ /* --- */ #define iopo_sha iopo_args[0] extern void XR_ShmAtIOPOrderProc (/* iopo */); /* XR_IOPOrder iopo; Do a shmat call on the IOP. If this is IOP 0, send a shmat order to all the vprocessors. */ extern void XR_ShmDtIOPOrderProc (/* iopo */); /* XR_IOPOrder iopo; Do a shmdt call on the IOP. If this is IOP 0, send a shmdt order to all the vprocessors. */ /* --- */ #define iopo_spawnCmd iopo_args[0] #define iopo_spawnWD iopo_args[1] #define iopo_spawnStdin iopo_args[2] #define iopo_spawnStdout iopo_args[3] #define iopo_spawnStderr iopo_args[4] #define iopo_spawnPID iopo_args[5] extern void XR_SpawnIOPOrderProc (/* iopo */); /* XR_IOPOrder iopo; Spawn child. The IOPOrder is linked into a global list, not set done until child terminates. Result in iopo->iopo_results[0] is termination status of child, or (-errno) if fork was unsuccessful. N.B. This is abortable, and has no cancel proc; iopo must be dynamically allocated. */ /* --- */ #define iopo_accessPath iopo_args[0] #define iopo_accessMode iopo_args[1] extern void XR_AccessIOPOrderProc (/* XR_IOPOrder iopo */); /* iopo->iopo_results[0] = access(path, mode) (or -errno on failure) */ /* --- */ #define iopo_chmodPath iopo_args[0] #define iopo_chmodMode iopo_args[1] extern void XR_ChModIOPOrderProc (/* XR_IOPOrder iopo */); /* iopo->iopo_results[0] = chmod(path, mode) (or -errno on failure) */ /* --- */ #define iopo_linkName1 iopo_args[0] #define iopo_linkName2 iopo_args[1] extern void XR_LinkIOPOrderProc (/* XR_IOPOrder iopo */); /* iopo->iopo_results[0] = link(name1, name2) (or -errno on failure) */ /* --- */ #define iopo_mkdirPath iopo_args[0] #define iopo_mkdirMode iopo_args[1] extern void XR_MkDirIOPOrderProc (/* XR_IOPOrder iopo */); /* iopo->iopo_results[0] = mkdir(path, mode) (or -errno on failure) */ /* --- */ #define iopo_mknodName iopo_args[0] #define iopo_mknodMode iopo_args[1] #define iopo_mknodDev iopo_args[2] extern void XR_MkNodIOPOrderProc (/* XR_IOPOrder iopo */); /* iopo->iopo_results[0] = mknod(path, mode, dev) (or -errno on failure) */ /* --- */ #define iopo_readlinkPath iopo_args[0] #define iopo_readlinkBuf iopo_args[1] #define iopo_readlinkBufsiz iopo_args[2] extern void XR_ReadLinkIOPOrderProc (/* XR_IOPOrder iopo */); /* iopo->iopo_results[0] = readlink(path, mode, dev) (or -errno on failure) */ /* --- */ #define iopo_renameFrom iopo_args[0] #define iopo_renameTo iopo_args[1] extern void XR_RenameIOPOrderProc (/* XR_IOPOrder iopo */); /* iopo->iopo_results[0] = rename(from, to) (or -errno on failure) */ /* --- */ #define iopo_rmdirName iopo_args[0] extern void XR_RmDirIOPOrderProc (/* XR_IOPOrder iopo */); /* iopo->iopo_results[0] = rmdir(name) (or -errno on failure) */ /* --- */ #define iopo_statPath iopo_args[0] #define iopo_statBuf iopo_args[1] extern void XR_StatIOPOrderProc (/* XR_IOPOrder iopo */); /* iopo->iopo_results[0] = stat(path, buf) (or -errno on failure) */ /* --- */ #define iopo_lstatPath iopo_args[0] #define iopo_lstatBuf iopo_args[1] extern void XR_LStatIOPOrderProc (/* XR_IOPOrder iopo */); /* iopo->iopo_results[0] = lstat(path, buf) (or -errno on failure) */ /* --- */ #define iopo_statfsPath iopo_args[0] #define iopo_statfsBuf iopo_args[1] extern void XR_StatFSIOPOrderProc (/* XR_IOPOrder iopo */); /* iopo->iopo_results[0] = statfs(path, buf) (or -errno on failure) */ /* --- */ #define iopo_symlinkName1 iopo_args[0] #define iopo_symlinkName2 iopo_args[1] extern void XR_SymLinkIOPOrderProc (/* XR_IOPOrder iopo */); /* iopo->iopo_results[0] = symlink(name1, name2) (or -errno on failure) */ /* --- */ #define iopo_truncatePath iopo_args[0] #define iopo_truncateLength iopo_args[1] extern void XR_TruncateIOPOrderProc (/* XR_IOPOrder iopo */); /* iopo->iopo_results[0] = truncate(path, length) (or -errno on failure) */ /* --- */ #define iopo_unlinkPath iopo_args[0] extern void XR_UnlinkIOPOrderProc (/* XR_IOPOrder iopo */); /* iopo->iopo_results[0] = truncate(path, length) (or -errno on failure) */ /* --- */ #define iopo_utimesFile iopo_args[0] #define iopo_utimesTVP iopo_args[1] extern void XR_UTimesIOPOrderProc (/* XR_IOPOrder iopo */); /* iopo->iopo_results[0] = stat(file, tvp) (or -errno on failure) */ /* --- */ #define iopo_eventSigNum iopo_args[0] #define iopo_eventInteresting iopo_args[1] extern void XR_RegisterInterestIOPOrderProc (/* XR_IOPOrder iopo */); /* iopo->iopo_results[0] = 0 after doing appropriate sigvec calls (or -errno on failure) */ /* --- */ #define iopo_fcntlCmd iopo_args[2] #define iopo_fcntlArg iopo_args[3] extern void XR_FCntlIOPOrderProc (/* XR_IOPOrder iopo */); /* iopo->iopo_results[0] = 0 after doing appropriate fcntl call (or -errno on failure) */ /* --- */ #define iopo_ioctlRequest iopo_args[2] #define iopo_ioctlArgp iopo_args[3] extern void XR_IOCtlIOPOrderProc (/* XR_IOPOrder iopo */); /* iopo->iopo_results[0] = 0 after doing appropriate ioctl call (or -errno on failure) */ /* * Utilities run by threads */ extern int XR_MProtect4(/* addr, len, prot, include_iops*/); /* XR_Pointer addr; unsigned len; int prot; bool include_iops; A version of MProtect that allows heap addresses, does no checking on on addr, and allows caller to specify whether or not IOPs are included. */ typedef unsigned long XR_FDEWhichIOP; /* how choose iop for descriptor */ #define XR_FDE_WHICH_IOP_FIRST 0 #define XR_FDE_WHICH_IOP_MOSTFREE 1 #define XR_FDE_WHICH_IOP_LEASTFREE 2 #define XR_FDE_WHICH_IOP_LAST 2 #define XR_FDE_WHICH_IOP_FROM_IOPE(iope) \ ((XR_FDEWhichIOP)(iope)) #define XR_FDE_WHICH_IOP_IS_IOPE(which) \ ((which) > XR_FDE_WHICH_IOP_LAST) #define XR_IOPE_FROM_WHICH_IOP(which) \ ((XR_IOPE)(which)) extern XR_FDE XR_AllocateFDE (/* fdKind, which */); /* XR_FDKind fdKind; XR_FDEWhichIOP which; Allocate an unused fde according to strategy which. Caller is assumed to hold uioArea monitor lock. On success, return the fde in BUSY (but not OPEN) state. On failure, set errno and return NIL. */ extern void XR_FreeFDE (/* fde */); /* XR_FDE fde; Free an fde. Caller is assumed to hold the fde exclusively, and to hold uioArea monitor lock. */ #define XR_IncFDEOpCnt(fde) \ (fde)->fde_opCnt += 1 #define XR_DecFDEOpCnt(fde) \ if( --((fde)->fde_opCnt) == 0 ) XR_Broadcast(&((fde)->fde_avail)) #define XR_FDCUsed(fdc) \ (fdc)->fdc_whenUsed = (++(XR_uioArea->uioa_opCnt)) /* Mark an FDC as used (for LRU). */ extern XR_FDC XR_AllocateFDC (/* fde */); /* XR_FDE fde; Allocate an fdc: - one that's not assigned to an fde, if possible ... - failing that, "steal" LRU FDC assigned to an unlocked fde ... - failing either of those, return NIL. Set fde->fde_fdc and fdc->fdc_fde pointers. Set fdc->fdc_valid = FALSE. Caller is assumed to hold uioArea monitor lock. */ extern void XR_FreeFDC(/* fdc */); /* XR_FDC fdc; Free an fdc. This updates the associated fde, if any, and sets fdc_valid = FALSE. Caller is assumed to hold the uioArea ml. */ extern XR_FDE XR_UIODoWithFDELocked(/* fildes, proc, x1, x2, x3 */); /* XR_Fildes fildes; int ( *proc)(* fde, x1, x2, x3 *); unsigned x1, x2, x3; Generic routine for UIO FDE parameter setting. The `proc' gets called with the FDE corresponding to `fildes' and arguments x1, x2, x3. If successful, proc should return a non-negative value; on error, it should set errno and return a negative value. If `proc' returns a non-negative value, then the FDE is returned from DoWithFDE; otherwise NIL is returned (with an error code in errno). Certain error conditions (EBADF ...) may cause DoWithFDE to set errno and return without calling proc. All this is done with the monitor lock held, so `proc' shouldn't block or do anything else that acquires the lock. */ #define XR_FDE_LOCKED_WORKER(name) \ int name (fde, x1, x2, x3) \ XR_FDE fde; \ unsigned x1, x2, x3; extern XR_FDE XR_UIODoWithNewFDE(/* fdKind, which, proc, x1, x2, x3 */); /* XR_FDKind fdKind; XR_FDEWhichIOP which; int ( *proc)(* fde, x1, x2, x3 *); unsigned x1, x2, x3; Generic routine for FDE creation. For fdKind, which interpretation see XR_AllocateFDE. The `proc' gets called with (newly-allocated) FDE (in state BUSY) and arguments x1, x2, x3. If successful, proc should return a non-negative value; on error, it should set errno and return a negative value. If `proc' returns a non-negative value, then the new FDE is returned from DoWithNewFDE in state OPEN; otherwise, the FDE is deallocated and DoWithNewFDE returns NIL (with an error code in errno). Certain error conditions (EMFILE ...) may cause DoWithNewFDE to set errno and return without calling proc. */ extern XR_FDE XR_UIODoWithOldAndNewFDE(/* fildes, proc, x1, x2 */); /* XR_IOPE iope; int ( *proc)(* fde, fdeNew, x1, x2 *); unsigned x1, x2; Generic routine for UIO with both and old and a newly-allocated FDE (e.g. accept, ...). The newly-allocated FDE comes from the same iop as the old one. The `proc' gets called with FDE's and arguments x1, x2. If successful, proc should return a non-negative value; on error, it should set errno and return a negative value. If `proc' returns a non-negative value, then the new FDE is returned from DoWithNewFDE; otherwise, the FDE is deallocated and DoWithNewFDE returns NIL (with an error code in errno). Certain error conditions (EMFILE ...) may cause DoWithNewFDE to set errno and return without calling proc. */ typedef struct XR_UIOWaitReadyProcRep { int (*wrp_proc)(/* XR_UIOWaitReadyProc self, XR_FDE fde */); XR_UIOWaitKinds wrp_how; XR_Ticks wrp_timeout; } * XR_UIOWaitReadyProc; /* Type of `waitReadyProc' parameter to UIODoWithFDEAndFDC, below. Called by (waitReadyProc->wrp_proc)(waitReadyProc, fde); Waits for fde to be ready (w/ appropriate direction, timeout, ...) Returns 0 on success, and (-1) with errno set on failure. */ extern int XR_UIODoWithFDEAndFDC(/* fildes, waitReadyProc, proc, x1, x2 */); /* XR_Fildes fildes; XR_UIOWaitReadyProc waitReadyProc; int (*proc)(XR_FDE fde, XR_FDC fdc, unsigned x1, unsigned x2); unsigned x1, x2; Generic routine for UIO with an FDE and an associated FDC. How to deal with EWOULDBLOCK is specified by `waitReadyProc'. The `proc' gets called with (locked) fde and fdc as arguments, together with the two client data values `x1' and `x2'. Ordinarily, the result of calling proc is returned from UIODoWithFDEAndFDC. If successful, `proc' should return a non-negative value; on error, it should set errno and return a negative value. Certain error conditions (EBADF, XR_EABORTED, ...) cause UIODoWithFDEAndFDC to set errno and return -1 without calling proc. */ #define XR_FDE_FDC_WORKER(name) \ int name (fde, fdc, x1, x2) \ XR_FDE fde; \ XR_FDC fdc; \ unsigned x1, x2; extern struct XR_UIOWaitReadyProcRep XR_UIOIn0WaitReadyProc; /* waitProc for first try on input (POLLIN) operations */ extern struct XR_UIOWaitReadyProcRep XR_UIOIn1WaitReadyProc; /* waitProc for later tries on input (POLLIN) operations */ extern struct XR_UIOWaitReadyProcRep XR_UIOOut0WaitReadyProc; extern struct XR_UIOWaitReadyProcRep XR_UIOOut1WaitReadyProc; extern struct XR_UIOWaitReadyProcRep XR_UIOPri0WaitReadyProc; extern struct XR_UIOWaitReadyProcRep XR_UIOInPri0WaitReadyProc; extern struct XR_UIOWaitReadyProcRep XR_UIOInOut0WaitReadyProc; extern struct XR_UIOWaitReadyProcRep XR_UIOPriOut0WaitReadyProc; extern struct XR_UIOWaitReadyProcRep XR_UIOInPriOut0WaitReadyProc; extern int XR_UIODoWithFDERefreshFDC(/* fildes, proc, x1, x2 */); /* XR_Fildes fildes; int (*proc)(XR_FDE fde, unsigned x1, unsigned x2); unsigned x1, x2; Generic routine for UIO with an FDE when the operation performed by proc would invalidate a cached FDC. How to deal with EWOULDBLOCK is specified by `waitReadyProc'. The `proc' gets called with (locked) fde as argument, together with the two client data values `x1' and `x2'. Ordinarily, the result of calling proc is returned. If successful, `proc' should return a non-negative value; on error, it should set errno and return a negative value. Certain error conditions (EBADF, XR_EABORTED, ...) cause UIODoWithFDERefreshFDC to set errno and return -1 without calling proc. */ #define XR_FDE_REFRESH_WORKER(name) \ int name (fde, x1, x2) \ XR_FDE fde; \ unsigned x1, x2; /* * For spawned (Unix) processes ... */ extern void XR_IOPSpawnChildDied(); /* Call on IOP that does spawns to reap children that have exited. */ #endif _XR_UIO_PRIVATE_