Annotation of 43BSDReno/contrib/isode-beta/compat/select.c, revision 1.1.1.1

1.1       root        1: /* select.c - select() abstractions */
                      2: 
                      3: #ifndef        lint
                      4: static char *rcsid = "$Header: /f/osi/compat/RCS/select.c,v 7.3 90/05/22 19:33:29 mrose Exp $";
                      5: #endif
                      6: 
                      7: /* 
                      8:  * $Header: /f/osi/compat/RCS/select.c,v 7.3 90/05/22 19:33:29 mrose Exp $
                      9:  *
                     10:  *
                     11:  * $Log:       select.c,v $
                     12:  * Revision 7.3  90/05/22  19:33:29  mrose
                     13:  * update
                     14:  * 
                     15:  * Revision 7.2  89/12/05  22:04:41  mrose
                     16:  * touch-up
                     17:  * 
                     18:  * Revision 7.1  89/11/30  23:53:31  mrose
                     19:  * touch-up
                     20:  * 
                     21:  * Revision 7.0  89/11/23  21:23:24  mrose
                     22:  * Release 6.0
                     23:  * 
                     24:  */
                     25: 
                     26: /*
                     27:  *                               NOTICE
                     28:  *
                     29:  *    Acquisition, use, and distribution of this module and related
                     30:  *    materials are subject to the restrictions of a license agreement.
                     31:  *    Consult the Preface in the User's Manual for the full terms of
                     32:  *    this agreement.
                     33:  *
                     34:  */
                     35: 
                     36: 
                     37: /* LINTLIBRARY */
                     38: 
                     39: #include <errno.h>
                     40: #include <stdio.h>
                     41: #include "manifest.h"
                     42: #include "tailor.h"
                     43: #include <sys/stat.h>
                     44: 
                     45: 
                     46: extern int errno;
                     47: 
                     48: /*  */
                     49: 
                     50: 
                     51: #ifdef SOCKETS
                     52: 
                     53: #include <sys/time.h>
                     54: 
                     55: 
                     56: /* Synchronous multiplexing:
                     57:        < 0 :   block indefinately
                     58:        = 0 :   poll
                     59:        > 0 :   wait
                     60:  */
                     61: 
                     62: int    selsocket (nfds, rfds, wfds, efds, secs)
                     63: int    nfds;
                     64: fd_set *rfds,
                     65:        *wfds,
                     66:        *efds;
                     67: int    secs;
                     68: {
                     69:     int     n;
                     70:     fd_set  ifds,
                     71:             ofds,
                     72:            xfds;
                     73:     struct timeval  tvs;
                     74:     register struct timeval *tv = &tvs;
                     75: 
                     76:     if (secs != NOTOK)
                     77:        tv -> tv_sec = secs, tv -> tv_usec = 0;
                     78:     else
                     79:        tv = NULL;
                     80: 
                     81:     if (rfds)
                     82:        ifds = *rfds;
                     83:     if (wfds)
                     84:        ofds = *wfds;
                     85:     if (efds)
                     86:        xfds = *efds;
                     87:     for (;;) {
                     88:        switch (n = select (nfds, rfds, wfds, efds, tv)) {
                     89:            case OK: 
                     90:                if (secs == NOTOK)
                     91:                    break;
                     92:                return OK;
                     93: 
                     94:            case NOTOK:
                     95:            default: 
                     96:                return n;
                     97:        }
                     98: 
                     99:        if (rfds)
                    100:            *rfds = ifds;
                    101:        if (wfds)
                    102:            *wfds = ofds;
                    103:        if (efds)
                    104:            *efds = xfds;
                    105:     }
                    106: }
                    107: #endif
                    108: 
                    109: /*  */
                    110: 
                    111: #ifdef EXOS
                    112: 
                    113: #ifdef SYS5
                    114: 
                    115: /* There seems to be a bug in the SYS5 EXOS select() routine when a socket can
                    116:    be read immediately (don't know about write).  The bug is that select()
                    117:    returns ZERO, and the mask is zero'd as well.  The code below explicitly
                    118:    checks for this case.
                    119: */
                    120: 
                    121: #include "sys/soioctl.h"
                    122: 
                    123: 
                    124: int    selsocket (nfds, rfds, wfds, efds, secs)
                    125: int    nfds;
                    126: fd_set *rfds,
                    127:        *wfds,
                    128:        *efds;
                    129: int    secs;
                    130: {
                    131:     register int    fd;
                    132:     int     n;
                    133:     fd_set  ifds,
                    134:             ofds;
                    135:     long    nbytes,
                    136:            usecs;
                    137: 
                    138:     if (secs != NOTOK)
                    139:        usecs = secs * 1000;
                    140:     else
                    141:        usecs = 0xffff; /* used to be ~(1L << (8 * sizeof usecs - 1)) */
                    142: 
                    143:     if (rfds)
                    144:        ifds = *rfds;
                    145:     if (wfds)
                    146:        ofds = *wfds;
                    147:     if (efds)
                    148:        FD_ZERO (efds);
                    149: 
                    150:     for (;;) {
                    151:        switch (n = select (nfds + 1, rfds, wfds, usecs)) {  /* +1 for UNISYS */
                    152:            case OK: 
                    153:                if (rfds)
                    154:                    for (fd = 0; fd < nfds; fd++)
                    155:                        if (FD_ISSET (fd, &ifds)
                    156:                                && ioctl (fd, FIONREAD, (char *) &nbytes)
                    157:                                            != NOTOK
                    158:                                && nbytes > 0) {
                    159:                            FD_SET (fd, rfds);
                    160:                            n++;
                    161:                        }
                    162:                if (n == 0 && secs == NOTOK)
                    163:                    break;
                    164:                return n;
                    165: 
                    166:            case NOTOK: 
                    167:            default: 
                    168:                return n;
                    169:        }
                    170: 
                    171:        if (rfds)
                    172:            *rfds = ifds;
                    173:        if (wfds)
                    174:            *wfds = ofds;
                    175:     }
                    176: }
                    177: #endif
                    178: #endif
                    179: 
                    180: /*  */
                    181: 
                    182: /* These routines are necessary because some network interfaces (i.e.,
                    183:    the CAMTEC) don't support real select()'s.  This code first calls any
                    184:    special interface-specific select() routines, and then calls the
                    185:    standard selsocket routine.
                    186: 
                    187:    In general, inter-working between network interfaces with a real select
                    188:    and interfaces with a real select won't work well.  You shouldn't expect
                    189:    to be able to handle parallel notification of events on several transport
                    190:    descriptors.  Hopefully, you will only need to work synchronously on one or
                    191:    two descriptors.
                    192:  */
                    193: 
                    194: static IFP    sfnx[FD_SETSIZE] = { NULL };
                    195: 
                    196: 
                    197: IFP    set_select_fd (fd, fnx)
                    198: int    fd;
                    199: IFP    fnx;
                    200: {
                    201:     IFP            ofnx;
                    202: 
                    203:     if (fd < 0 || fd >= FD_SETSIZE)
                    204:        return NULLIFP;
                    205: 
                    206:     ofnx = sfnx[fd];
                    207:     sfnx[fd] = fnx;
                    208: 
                    209:     return ofnx;
                    210: }
                    211: 
                    212: set_select_mask (mask,fnx)
                    213: fd_set *mask;
                    214: IFP    fnx;
                    215: {
                    216:     int        fd;
                    217: 
                    218:     for (fd = 0; fd < FD_SETSIZE; fd++)
                    219:        if (FD_ISSET (fd, mask))
                    220:            sfnx[fd] = fnx;
                    221: }
                    222: 
                    223: /*  */
                    224: 
                    225: int    xselect (nfds, rfds, wfds, efds, secs)
                    226: int    nfds;
                    227: fd_set *rfds,
                    228:        *wfds,
                    229:        *efds;
                    230: int    secs;
                    231: {
                    232:     int            n;
                    233:     register int    fd;
                    234:     fd_set  ifds,
                    235:            ofds,
                    236:            xfds;
                    237:     static int nsysfds = NOTOK;
                    238: 
                    239:     if (nsysfds == NOTOK)
                    240:        nsysfds = getdtablesize ();
                    241:     if (nfds > FD_SETSIZE)
                    242:        nfds = FD_SETSIZE;
                    243:     if (nfds > nsysfds + 1)
                    244:        nfds = nsysfds + 1;
                    245: 
                    246:     for (fd = 0; fd < nfds; fd++)
                    247:        if (sfnx[fd] != NULLIFP
                    248:                && ((rfds && FD_ISSET (fd, rfds))
                    249:                        || (wfds && FD_ISSET (fd, wfds))
                    250:                        || (efds && FD_ISSET (fd, efds))))
                    251:            return ((*sfnx[fd]) (nfds, rfds, wfds, efds, secs));
                    252: 
                    253:     if (rfds)
                    254:        ifds = *rfds;   /* struct copy */
                    255:     if (wfds)
                    256:        ofds = *wfds;   /* struct copy */
                    257:     if (efds)
                    258:        xfds = *efds;   /* struct copy */
                    259: 
                    260:     if ((n = selsocket (nfds, rfds, wfds, efds, secs)) != NOTOK)
                    261:        return n;
                    262: 
                    263:     if (errno == EBADF) {
                    264:        struct stat st;
                    265: 
                    266:        if (rfds)
                    267:            FD_ZERO (rfds);
                    268:        if (wfds)
                    269:            FD_ZERO (wfds);
                    270:        if (efds)
                    271:            FD_ZERO (efds);
                    272: 
                    273:        n = 0;
                    274:        for (fd = 0; fd < nfds; fd++)
                    275:            if (((rfds && FD_ISSET (fd, &ifds))
                    276:                        || (wfds && FD_ISSET (fd, &ofds))
                    277:                        || (efds && FD_ISSET (fd, &xfds)))
                    278:                    && fstat (fd, &st) == NOTOK) {
                    279:                if (rfds && FD_ISSET (fd, &ifds))
                    280:                    FD_SET (fd, rfds);
                    281:                if (wfds && FD_ISSET (fd, &ofds))
                    282:                    FD_SET (fd, wfds);
                    283:                if (efds && FD_ISSET (fd, &xfds))
                    284:                    FD_SET (fd, efds);
                    285: 
                    286:                SLOG (compat_log, LLOG_EXCEPTIONS, "",
                    287:                      ("fd %d has gone bad", fd));
                    288:                n++;
                    289:            }
                    290: 
                    291:        if (n)
                    292:            return n;
                    293: 
                    294:        errno = EBADF;
                    295:     }
                    296: 
                    297:     return NOTOK;
                    298: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.