|
|
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);
}