|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T s
Length: 4373 (0x1115) Types: TextFile Names: »select.c«
└─⟦3d0c2be1b⟧ Bits:30001254 ISODE-5.0 Tape └─⟦eba4602b1⟧ »./isode-5.0.tar.Z« └─⟦d3ac74d73⟧ └─⟦this⟧ »isode-5.0/compat/select.c«
/* select.c - select() abstractions */ #ifndef lint static char *rcsid = "$Header: /f/osi/compat/RCS/select.c,v 6.0 89/03/18 23:25:33 mrose Rel $"; #endif /* * $Header: /f/osi/compat/RCS/select.c,v 6.0 89/03/18 23:25:33 mrose Rel $ * * * $Log: select.c,v $ * Revision 6.0 89/03/18 23:25:33 mrose * Release 5.0 * */ /* * NOTICE * * Acquisition, use, and distribution of this module and related * materials are subject to the restrictions of a license agreement. * Consult the Preface in the User's Manual for the full terms of * this agreement. * */ /* LINTLIBRARY */ #include <errno.h> #include <stdio.h> #include "manifest.h" extern int errno; /* \f */ #if defined(SOCKETS) #include <sys/time.h> /* Synchronous multiplexing: < 0 : block indefinately = 0 : poll > 0 : wait */ int selsocket (nfds, rfds, wfds, efds, secs) int nfds; fd_set *rfds, *wfds, *efds; int secs; { int n; fd_set ifds, ofds, xfds; struct timeval tvs; register struct timeval *tv = &tvs; if (secs != NOTOK) tv -> tv_sec = secs, tv -> tv_usec = 0; else tv = NULL; if (rfds) ifds = *rfds; if (wfds) ofds = *wfds; if (efds) xfds = *efds; for (;;) { switch (n = select (nfds, rfds, wfds, efds, tv)) { case OK: if (secs == NOTOK) break; return OK; case NOTOK: if (errno == EINTR && secs == NOTOK) break; /* else fall */ default: return n; } if (rfds) *rfds = ifds; if (wfds) *wfds = ofds; if (efds) *efds = xfds; } } #endif /* \f */ /* \f */ #ifdef EXOS #ifdef SYS5 /* There seems to be a bug in the SYS5 EXOS select() routine when a socket can be read immediately (don't know about write). The bug is that select() returns ZERO, and the mask is zero'd as well. The code below explicitly checks for this case. */ #include "sys/soioctl.h" int selsocket (nfds, rfds, wfds, efds, secs) int nfds; fd_set *rfds, *wfds, *efds; int secs; { register int fd; int n; fd_set ifds, ofds; long nbytes, usecs; if (secs != NOTOK) usecs = secs * 1000; else usecs = ~(1L << (8 * sizeof usecs - 1)); if (rfds) ifds = *rfds; if (wfds) ofds = *wfds; if (efds) FD_ZERO (efds); for (;;) { switch (n = select (nfds, rfds, wfds, usecs)) { case OK: if (rfds) for (fd = 0; fd < nfds; fd++) if (FD_ISSET (fd, &ifds) && ioctl (fd, FIONREAD, (char *) &nbytes) != NOTOK && nbytes > 0) { FD_SET (fd, rfds); n++; } if (n == 0 && secs == NOTOK) break; return n; case NOTOK: if (errno == EINTR && secs == NOTOK) break; /* else fall */ default: return n; } if (rfds) *rfds = ifds; if (wfds) *wfds = ofds; } } #endif #endif /* \f */ /* These routines are necessary because some network interfaces (i.e., the CAMTEC) don't support real select()'s. This code first calls any special interface-specific select() routines, and then calls the standard selsocket routine. In general, inter-working between network interfaces with a real select and interfaces with a real select won't work well. You shouldn't expect to be able to handle parallel notification of events on several transport descriptors. Hopefully, you will only need to work synchronously on one or two descriptors. */ static IFP sfnx[FD_SETSIZE] = { NULL }; IFP set_select_fd (fd, fnx) int fd; IFP fnx; { IFP ofnx; if (fd < 0 || fd >= FD_SETSIZE) return NULLIFP; ofnx = sfnx[fd]; sfnx[fd] = fnx; return ofnx; } set_select_mask (mask,fnx) fd_set *mask; IFP fnx; { int fd; for (fd = 0; fd < FD_SETSIZE; fd++) if (FD_ISSET (fd, mask)) sfnx[fd] = fnx; } /* \f */ int xselect (nfds, rfds, wfds, efds, secs) int nfds; fd_set *rfds, *wfds, *efds; int secs; { register int fd; if (nfds > FD_SETSIZE) nfds = FD_SETSIZE; if (nfds > (fd = getdtablesize () + 1)) nfds = fd; for (fd = 0; fd < nfds; fd++) if (sfnx[fd] != NULLIFP && ((rfds && FD_ISSET (fd, rfds)) || (wfds && FD_ISSET (fd, wfds)) || (efds && FD_ISSET (fd, efds)))) return ((*sfnx[fd]) (nfds, rfds, wfds, efds, secs)); return selsocket (nfds, rfds, wfds, efds, secs); }