DataMuseum.dk

Presents historical artifacts from the history of:

DKUUG/EUUG Conference tapes

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about DKUUG/EUUG Conference tapes

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - metrics - download
Index: T s

⟦ef3533403⟧ TextFile

    Length: 4373 (0x1115)
    Types: TextFile
    Names: »select.c«

Derivation

└─⟦3d0c2be1b⟧ Bits:30001254 ISODE-5.0 Tape
    └─⟦eba4602b1⟧ »./isode-5.0.tar.Z« 
        └─⟦d3ac74d73⟧ 
            └─⟦this⟧ »isode-5.0/compat/select.c« 

TextFile

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