Annotation of Net2/kern/sys_generic.c, revision 1.1.1.2

1.1       root        1: /*
                      2:  * Copyright (c) 1982, 1986, 1989 Regents of the University of California.
                      3:  * All rights reserved.
                      4:  *
                      5:  * Redistribution and use in source and binary forms, with or without
                      6:  * modification, are permitted provided that the following conditions
                      7:  * are met:
                      8:  * 1. Redistributions of source code must retain the above copyright
                      9:  *    notice, this list of conditions and the following disclaimer.
                     10:  * 2. Redistributions in binary form must reproduce the above copyright
                     11:  *    notice, this list of conditions and the following disclaimer in the
                     12:  *    documentation and/or other materials provided with the distribution.
                     13:  * 3. All advertising materials mentioning features or use of this software
                     14:  *    must display the following acknowledgement:
                     15:  *     This product includes software developed by the University of
                     16:  *     California, Berkeley and its contributors.
                     17:  * 4. Neither the name of the University nor the names of its contributors
                     18:  *    may be used to endorse or promote products derived from this software
                     19:  *    without specific prior written permission.
                     20:  *
                     21:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
                     22:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     23:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     24:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
                     25:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     26:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     27:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     28:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     29:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     30:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     31:  * SUCH DAMAGE.
                     32:  *
                     33:  *     @(#)sys_generic.c       7.30 (Berkeley) 5/30/91
1.1.1.2 ! root       34:  *
        !            35:  * PATCHES MAGIC                LEVEL   PATCH THAT GOT US HERE
        !            36:  * --------------------         -----   ----------------------
        !            37:  * CURRENT PATCH LEVEL:         1       00061
        !            38:  * --------------------         -----   ----------------------
        !            39:  *
        !            40:  * 11 Dec 92   Williams Jolitz         Fixed tty handling
1.1       root       41:  */
                     42: 
                     43: #include "param.h"
                     44: #include "systm.h"
                     45: #include "filedesc.h"
                     46: #include "ioctl.h"
                     47: #include "file.h"
                     48: #include "socketvar.h"
                     49: #include "proc.h"
                     50: #include "uio.h"
                     51: #include "kernel.h"
                     52: #include "stat.h"
                     53: #include "malloc.h"
                     54: #ifdef KTRACE
                     55: #include "ktrace.h"
                     56: #endif
                     57: 
                     58: /*
                     59:  * Read system call.
                     60:  */
                     61: /* ARGSUSED */
                     62: read(p, uap, retval)
                     63:        struct proc *p;
                     64:        register struct args {
                     65:                int     fdes;
                     66:                char    *cbuf;
                     67:                unsigned count;
                     68:        } *uap;
                     69:        int *retval;
                     70: {
                     71:        register struct file *fp;
                     72:        register struct filedesc *fdp = p->p_fd;
                     73:        struct uio auio;
                     74:        struct iovec aiov;
                     75:        long cnt, error = 0;
                     76: #ifdef KTRACE
                     77:        struct iovec ktriov;
                     78: #endif
                     79: 
                     80:        if (((unsigned)uap->fdes) >= fdp->fd_nfiles ||
                     81:            (fp = fdp->fd_ofiles[uap->fdes]) == NULL ||
                     82:            (fp->f_flag & FREAD) == 0)
                     83:                return (EBADF);
                     84:        aiov.iov_base = (caddr_t)uap->cbuf;
                     85:        aiov.iov_len = uap->count;
                     86:        auio.uio_iov = &aiov;
                     87:        auio.uio_iovcnt = 1;
                     88:        auio.uio_resid = uap->count;
                     89:        auio.uio_rw = UIO_READ;
                     90:        auio.uio_segflg = UIO_USERSPACE;
                     91:        auio.uio_procp = p;
                     92: #ifdef KTRACE
                     93:        /*
                     94:         * if tracing, save a copy of iovec
                     95:         */
                     96:        if (KTRPOINT(p, KTR_GENIO))
                     97:                ktriov = aiov;
                     98: #endif
                     99:        cnt = uap->count;
                    100:        if (error = (*fp->f_ops->fo_read)(fp, &auio, fp->f_cred))
                    101:                if (auio.uio_resid != cnt && (error == ERESTART ||
                    102:                    error == EINTR || error == EWOULDBLOCK))
                    103:                        error = 0;
                    104:        cnt -= auio.uio_resid;
                    105: #ifdef KTRACE
                    106:        if (KTRPOINT(p, KTR_GENIO) && error == 0)
                    107:                ktrgenio(p->p_tracep, uap->fdes, UIO_READ, &ktriov, cnt, error);
                    108: #endif
                    109:        *retval = cnt;
                    110:        return (error);
                    111: }
                    112: 
                    113: /*
                    114:  * Scatter read system call.
                    115:  */
                    116: /* ARGSUSED */
                    117: readv(p, uap, retval)
                    118:        struct proc *p;
                    119:        register struct args {
                    120:                int     fdes;
                    121:                struct  iovec *iovp;
                    122:                unsigned iovcnt;
                    123:        } *uap;
                    124:        int *retval;
                    125: {
                    126:        register struct file *fp;
                    127:        register struct filedesc *fdp = p->p_fd;
                    128:        struct uio auio;
                    129:        register struct iovec *iov;
                    130:        struct iovec *saveiov;
                    131:        struct iovec aiov[UIO_SMALLIOV];
                    132:        long i, cnt, error = 0;
                    133:        unsigned iovlen;
                    134: #ifdef KTRACE
                    135:        struct iovec *ktriov = NULL;
                    136: #endif
                    137: 
                    138:        if (((unsigned)uap->fdes) >= fdp->fd_nfiles ||
                    139:            (fp = fdp->fd_ofiles[uap->fdes]) == NULL ||
                    140:            (fp->f_flag & FREAD) == 0)
                    141:                return (EBADF);
                    142:        /* note: can't use iovlen until iovcnt is validated */
                    143:        iovlen = uap->iovcnt * sizeof (struct iovec);
                    144:        if (uap->iovcnt > UIO_SMALLIOV) {
                    145:                if (uap->iovcnt > UIO_MAXIOV)
                    146:                        return (EINVAL);
                    147:                MALLOC(iov, struct iovec *, iovlen, M_IOV, M_WAITOK);
                    148:                saveiov = iov;
                    149:        } else
                    150:                iov = aiov;
                    151:        auio.uio_iov = iov;
                    152:        auio.uio_iovcnt = uap->iovcnt;
                    153:        auio.uio_rw = UIO_READ;
                    154:        auio.uio_segflg = UIO_USERSPACE;
                    155:        auio.uio_procp = p;
                    156:        if (error = copyin((caddr_t)uap->iovp, (caddr_t)iov, iovlen))
                    157:                goto done;
                    158:        auio.uio_resid = 0;
                    159:        for (i = 0; i < uap->iovcnt; i++) {
                    160:                if (iov->iov_len < 0) {
                    161:                        error = EINVAL;
                    162:                        goto done;
                    163:                }
                    164:                auio.uio_resid += iov->iov_len;
                    165:                if (auio.uio_resid < 0) {
                    166:                        error = EINVAL;
                    167:                        goto done;
                    168:                }
                    169:                iov++;
                    170:        }
                    171: #ifdef KTRACE
                    172:        /*
                    173:         * if tracing, save a copy of iovec
                    174:         */
                    175:        if (KTRPOINT(p, KTR_GENIO))  {
                    176:                MALLOC(ktriov, struct iovec *, iovlen, M_TEMP, M_WAITOK);
                    177:                bcopy((caddr_t)auio.uio_iov, (caddr_t)ktriov, iovlen);
                    178:        }
                    179: #endif
                    180:        cnt = auio.uio_resid;
                    181:        if (error = (*fp->f_ops->fo_read)(fp, &auio, fp->f_cred))
                    182:                if (auio.uio_resid != cnt && (error == ERESTART ||
                    183:                    error == EINTR || error == EWOULDBLOCK))
                    184:                        error = 0;
                    185:        cnt -= auio.uio_resid;
                    186: #ifdef KTRACE
                    187:        if (ktriov != NULL) {
                    188:                if (error == 0)
                    189:                        ktrgenio(p->p_tracep, uap->fdes, UIO_READ, ktriov,
                    190:                            cnt, error);
                    191:                FREE(ktriov, M_TEMP);
                    192:        }
                    193: #endif
                    194:        *retval = cnt;
                    195: done:
                    196:        if (uap->iovcnt > UIO_SMALLIOV)
                    197:                FREE(saveiov, M_IOV);
                    198:        return (error);
                    199: }
                    200: 
                    201: /*
                    202:  * Write system call
                    203:  */
                    204: write(p, uap, retval)
                    205:        struct proc *p;
                    206:        register struct args {
                    207:                int     fdes;
                    208:                char    *cbuf;
                    209:                unsigned count;
                    210:        } *uap;
                    211:        int *retval;
                    212: {
                    213:        register struct file *fp;
                    214:        register struct filedesc *fdp = p->p_fd;
                    215:        struct uio auio;
                    216:        struct iovec aiov;
                    217:        long cnt, error = 0;
                    218: #ifdef KTRACE
                    219:        struct iovec ktriov;
                    220: #endif
                    221: 
                    222:        if (((unsigned)uap->fdes) >= fdp->fd_nfiles ||
                    223:            (fp = fdp->fd_ofiles[uap->fdes]) == NULL ||
                    224:            (fp->f_flag & FWRITE) == 0)
                    225:                return (EBADF);
                    226:        aiov.iov_base = (caddr_t)uap->cbuf;
                    227:        aiov.iov_len = uap->count;
                    228:        auio.uio_iov = &aiov;
                    229:        auio.uio_iovcnt = 1;
                    230:        auio.uio_resid = uap->count;
                    231:        auio.uio_rw = UIO_WRITE;
                    232:        auio.uio_segflg = UIO_USERSPACE;
                    233:        auio.uio_procp = p;
                    234: #ifdef KTRACE
                    235:        /*
                    236:         * if tracing, save a copy of iovec
                    237:         */
                    238:        if (KTRPOINT(p, KTR_GENIO))
                    239:                ktriov = aiov;
                    240: #endif
                    241:        cnt = uap->count;
                    242:        if (error = (*fp->f_ops->fo_write)(fp, &auio, fp->f_cred)) {
                    243:                if (auio.uio_resid != cnt && (error == ERESTART ||
                    244:                    error == EINTR || error == EWOULDBLOCK))
                    245:                        error = 0;
                    246:                if (error == EPIPE)
                    247:                        psignal(p, SIGPIPE);
                    248:        }
                    249:        cnt -= auio.uio_resid;
                    250: #ifdef KTRACE
                    251:        if (KTRPOINT(p, KTR_GENIO) && error == 0)
                    252:                ktrgenio(p->p_tracep, uap->fdes, UIO_WRITE,
                    253:                    &ktriov, cnt, error);
                    254: #endif
                    255:        *retval = cnt;
                    256:        return (error);
                    257: }
                    258: 
                    259: /*
                    260:  * Gather write system call
                    261:  */
                    262: writev(p, uap, retval)
                    263:        struct proc *p;
                    264:        register struct args {
                    265:                int     fdes;
                    266:                struct  iovec *iovp;
                    267:                unsigned iovcnt;
                    268:        } *uap;
                    269:        int *retval;
                    270: {
                    271:        register struct file *fp;
                    272:        register struct filedesc *fdp = p->p_fd;
                    273:        struct uio auio;
                    274:        register struct iovec *iov;
                    275:        struct iovec *saveiov;
                    276:        struct iovec aiov[UIO_SMALLIOV];
                    277:        long i, cnt, error = 0;
                    278:        unsigned iovlen;
                    279: #ifdef KTRACE
                    280:        struct iovec *ktriov = NULL;
                    281: #endif
                    282: 
                    283:        if (((unsigned)uap->fdes) >= fdp->fd_nfiles ||
                    284:            (fp = fdp->fd_ofiles[uap->fdes]) == NULL ||
                    285:            (fp->f_flag & FWRITE) == 0)
                    286:                return (EBADF);
                    287:        /* note: can't use iovlen until iovcnt is validated */
                    288:        iovlen = uap->iovcnt * sizeof (struct iovec);
                    289:        if (uap->iovcnt > UIO_SMALLIOV) {
                    290:                if (uap->iovcnt > UIO_MAXIOV)
                    291:                        return (EINVAL);
                    292:                MALLOC(iov, struct iovec *, iovlen, M_IOV, M_WAITOK);
                    293:                saveiov = iov;
                    294:        } else
                    295:                iov = aiov;
                    296:        auio.uio_iov = iov;
                    297:        auio.uio_iovcnt = uap->iovcnt;
                    298:        auio.uio_rw = UIO_WRITE;
                    299:        auio.uio_segflg = UIO_USERSPACE;
                    300:        auio.uio_procp = p;
                    301:        if (error = copyin((caddr_t)uap->iovp, (caddr_t)iov, iovlen))
                    302:                goto done;
                    303:        auio.uio_resid = 0;
                    304:        for (i = 0; i < uap->iovcnt; i++) {
                    305:                if (iov->iov_len < 0) {
                    306:                        error = EINVAL;
                    307:                        goto done;
                    308:                }
                    309:                auio.uio_resid += iov->iov_len;
                    310:                if (auio.uio_resid < 0) {
                    311:                        error = EINVAL;
                    312:                        goto done;
                    313:                }
                    314:                iov++;
                    315:        }
                    316: #ifdef KTRACE
                    317:        /*
                    318:         * if tracing, save a copy of iovec
                    319:         */
                    320:        if (KTRPOINT(p, KTR_GENIO))  {
                    321:                MALLOC(ktriov, struct iovec *, iovlen, M_TEMP, M_WAITOK);
                    322:                bcopy((caddr_t)auio.uio_iov, (caddr_t)ktriov, iovlen);
                    323:        }
                    324: #endif
                    325:        cnt = auio.uio_resid;
                    326:        if (error = (*fp->f_ops->fo_write)(fp, &auio, fp->f_cred)) {
                    327:                if (auio.uio_resid != cnt && (error == ERESTART ||
                    328:                    error == EINTR || error == EWOULDBLOCK))
                    329:                        error = 0;
                    330:                if (error == EPIPE)
                    331:                        psignal(p, SIGPIPE);
                    332:        }
                    333:        cnt -= auio.uio_resid;
                    334: #ifdef KTRACE
                    335:        if (ktriov != NULL) {
                    336:                if (error == 0)
                    337:                        ktrgenio(p->p_tracep, uap->fdes, UIO_WRITE,
                    338:                                ktriov, cnt, error);
                    339:                FREE(ktriov, M_TEMP);
                    340:        }
                    341: #endif
                    342:        *retval = cnt;
                    343: done:
                    344:        if (uap->iovcnt > UIO_SMALLIOV)
                    345:                FREE(saveiov, M_IOV);
                    346:        return (error);
                    347: }
                    348: 
                    349: /*
                    350:  * Ioctl system call
                    351:  */
                    352: /* ARGSUSED */
                    353: ioctl(p, uap, retval)
                    354:        struct proc *p;
                    355:        register struct args {
                    356:                int     fdes;
                    357:                int     cmd;
                    358:                caddr_t cmarg;
                    359:        } *uap;
                    360:        int *retval;
                    361: {
                    362:        register struct file *fp;
                    363:        register struct filedesc *fdp = p->p_fd;
                    364:        register int com, error;
                    365:        register u_int size;
                    366:        caddr_t memp = 0;
                    367: #define STK_PARAMS     128
                    368:        char stkbuf[STK_PARAMS];
                    369:        caddr_t data = stkbuf;
                    370:        int tmp;
                    371: 
                    372:        if ((unsigned)uap->fdes >= fdp->fd_nfiles ||
                    373:            (fp = fdp->fd_ofiles[uap->fdes]) == NULL)
                    374:                return (EBADF);
                    375:        if ((fp->f_flag & (FREAD|FWRITE)) == 0)
                    376:                return (EBADF);
                    377:        com = uap->cmd;
                    378: 
                    379:        if (com == FIOCLEX) {
                    380:                fdp->fd_ofileflags[uap->fdes] |= UF_EXCLOSE;
                    381:                return (0);
                    382:        }
                    383:        if (com == FIONCLEX) {
                    384:                fdp->fd_ofileflags[uap->fdes] &= ~UF_EXCLOSE;
                    385:                return (0);
                    386:        }
                    387: 
                    388:        /*
                    389:         * Interpret high order word to find
                    390:         * amount of data to be copied to/from the
                    391:         * user's address space.
                    392:         */
                    393:        size = IOCPARM_LEN(com);
                    394:        if (size > IOCPARM_MAX)
                    395:                return (ENOTTY);
                    396:        if (size > sizeof (stkbuf)) {
                    397:                memp = (caddr_t)malloc((u_long)size, M_IOCTLOPS, M_WAITOK);
                    398:                data = memp;
                    399:        }
                    400:        if (com&IOC_IN) {
                    401:                if (size) {
                    402:                        error = copyin(uap->cmarg, data, (u_int)size);
                    403:                        if (error) {
                    404:                                if (memp)
                    405:                                        free(memp, M_IOCTLOPS);
                    406:                                return (error);
                    407:                        }
                    408:                } else
                    409:                        *(caddr_t *)data = uap->cmarg;
                    410:        } else if ((com&IOC_OUT) && size)
                    411:                /*
                    412:                 * Zero the buffer so the user always
                    413:                 * gets back something deterministic.
                    414:                 */
                    415:                bzero(data, size);
                    416:        else if (com&IOC_VOID)
                    417:                *(caddr_t *)data = uap->cmarg;
                    418: 
                    419:        switch (com) {
                    420: 
                    421:        case FIONBIO:
                    422:                if (tmp = *(int *)data)
                    423:                        fp->f_flag |= FNONBLOCK;
                    424:                else
                    425:                        fp->f_flag &= ~FNONBLOCK;
                    426:                error = (*fp->f_ops->fo_ioctl)(fp, FIONBIO, (caddr_t)&tmp, p);
                    427:                break;
                    428: 
                    429:        case FIOASYNC:
                    430:                if (tmp = *(int *)data)
                    431:                        fp->f_flag |= FASYNC;
                    432:                else
                    433:                        fp->f_flag &= ~FASYNC;
                    434:                error = (*fp->f_ops->fo_ioctl)(fp, FIOASYNC, (caddr_t)&tmp, p);
                    435:                break;
                    436: 
                    437:        case FIOSETOWN:
                    438:                tmp = *(int *)data;
                    439:                if (fp->f_type == DTYPE_SOCKET) {
                    440:                        ((struct socket *)fp->f_data)->so_pgid = tmp;
                    441:                        error = 0;
                    442:                        break;
                    443:                }
                    444:                if (tmp <= 0) {
                    445:                        tmp = -tmp;
                    446:                } else {
                    447:                        struct proc *p1 = pfind(tmp);
                    448:                        if (p1 == 0) {
                    449:                                error = ESRCH;
                    450:                                break;
                    451:                        }
                    452:                        tmp = p1->p_pgrp->pg_id;
                    453:                }
                    454:                error = (*fp->f_ops->fo_ioctl)
                    455:                        (fp, (int)TIOCSPGRP, (caddr_t)&tmp, p);
                    456:                break;
                    457: 
                    458:        case FIOGETOWN:
                    459:                if (fp->f_type == DTYPE_SOCKET) {
                    460:                        error = 0;
                    461:                        *(int *)data = ((struct socket *)fp->f_data)->so_pgid;
                    462:                        break;
                    463:                }
                    464:                error = (*fp->f_ops->fo_ioctl)(fp, (int)TIOCGPGRP, data, p);
                    465:                *(int *)data = -*(int *)data;
                    466:                break;
                    467: 
                    468:        default:
                    469:                error = (*fp->f_ops->fo_ioctl)(fp, com, data, p);
                    470:                /*
                    471:                 * Copy any data to user, size was
                    472:                 * already set and checked above.
                    473:                 */
                    474:                if (error == 0 && (com&IOC_OUT) && size)
                    475:                        error = copyout(data, uap->cmarg, (u_int)size);
                    476:                break;
                    477:        }
                    478:        if (memp)
                    479:                free(memp, M_IOCTLOPS);
                    480:        return (error);
                    481: }
                    482: 
                    483: int    selwait, nselcoll;
                    484: 
                    485: /*
                    486:  * Select system call.
                    487:  */
                    488: select(p, uap, retval)
                    489:        register struct proc *p;
                    490:        register struct args {
                    491:                int     nd;
                    492:                fd_set  *in, *ou, *ex;
                    493:                struct  timeval *tv;
                    494:        } *uap;
                    495:        int *retval;
                    496: {
                    497:        fd_set ibits[3], obits[3];
                    498:        struct timeval atv;
                    499:        int s, ncoll, ni, error = 0, timo;
                    500: 
                    501:        bzero((caddr_t)ibits, sizeof(ibits));
                    502:        bzero((caddr_t)obits, sizeof(obits));
                    503:        if (uap->nd > p->p_fd->fd_nfiles)
                    504:                uap->nd = p->p_fd->fd_nfiles;   /* forgiving; slightly wrong */
                    505:        ni = howmany(uap->nd, NFDBITS);
                    506: 
                    507: #define        getbits(name, x) \
                    508:        if (uap->name) { \
                    509:                error = copyin((caddr_t)uap->name, (caddr_t)&ibits[x], \
                    510:                    (unsigned)(ni * sizeof(fd_mask))); \
                    511:                if (error) \
                    512:                        goto done; \
                    513:        }
                    514:        getbits(in, 0);
                    515:        getbits(ou, 1);
                    516:        getbits(ex, 2);
                    517: #undef getbits
                    518: 
                    519:        if (uap->tv) {
                    520:                error = copyin((caddr_t)uap->tv, (caddr_t)&atv,
                    521:                        sizeof (atv));
                    522:                if (error)
                    523:                        goto done;
                    524:                if (itimerfix(&atv)) {
                    525:                        error = EINVAL;
                    526:                        goto done;
                    527:                }
                    528:                s = splhigh(); timevaladd(&atv, &time); splx(s);
                    529:                timo = hzto(&atv);
                    530:        } else
                    531:                timo = 0;
                    532: retry:
                    533:        ncoll = nselcoll;
                    534:        p->p_flag |= SSEL;
                    535:        error = selscan(p, ibits, obits, uap->nd, retval);
                    536:        if (error || *retval)
                    537:                goto done;
                    538:        s = splhigh();
                    539:        /* this should be timercmp(&time, &atv, >=) */
                    540:        if (uap->tv && (time.tv_sec > atv.tv_sec ||
                    541:            time.tv_sec == atv.tv_sec && time.tv_usec >= atv.tv_usec)) {
                    542:                splx(s);
                    543:                goto done;
                    544:        }
                    545:        if ((p->p_flag & SSEL) == 0 || nselcoll != ncoll) {
                    546:                splx(s);
                    547:                goto retry;
                    548:        }
                    549:        p->p_flag &= ~SSEL;
                    550:        error = tsleep((caddr_t)&selwait, PSOCK | PCATCH, "select", timo);
                    551:        splx(s);
                    552:        if (error == 0)
                    553:                goto retry;
                    554: done:
                    555:        p->p_flag &= ~SSEL;
                    556:        /* select is not restarted after signals... */
                    557:        if (error == ERESTART)
                    558:                error = EINTR;
                    559:        if (error == EWOULDBLOCK)
                    560:                error = 0;
                    561: #define        putbits(name, x) \
                    562:        if (uap->name) { \
                    563:                int error2 = copyout((caddr_t)&obits[x], (caddr_t)uap->name, \
                    564:                    (unsigned)(ni * sizeof(fd_mask))); \
                    565:                if (error2) \
                    566:                        error = error2; \
                    567:        }
                    568:        if (error == 0) {
                    569:                putbits(in, 0);
                    570:                putbits(ou, 1);
                    571:                putbits(ex, 2);
                    572: #undef putbits
                    573:        }
                    574:        return (error);
                    575: }
                    576: 
1.1.1.2 ! root      577: int
        !           578: selscan(struct proc *p, fd_set *ibits, fd_set *obits, int nfd, int *retval)
1.1       root      579: {
                    580:        register struct filedesc *fdp = p->p_fd;
                    581:        register int which, i, j;
                    582:        register fd_mask bits;
                    583:        int flag;
                    584:        struct file *fp;
                    585:        int error = 0, n = 0;
                    586: 
                    587:        for (which = 0; which < 3; which++) {
                    588:                switch (which) {
                    589: 
                    590:                case 0:
                    591:                        flag = FREAD; break;
                    592: 
                    593:                case 1:
                    594:                        flag = FWRITE; break;
                    595: 
                    596:                case 2:
                    597:                        flag = 0; break;
                    598:                }
                    599:                for (i = 0; i < nfd; i += NFDBITS) {
                    600:                        bits = ibits[which].fds_bits[i/NFDBITS];
                    601:                        while ((j = ffs(bits)) && i + --j < nfd) {
                    602:                                bits &= ~(1 << j);
                    603:                                fp = fdp->fd_ofiles[i + j];
                    604:                                if (fp == NULL) {
                    605:                                        error = EBADF;
                    606:                                        break;
                    607:                                }
                    608:                                if ((*fp->f_ops->fo_select)(fp, flag, p)) {
                    609:                                        FD_SET(i + j, &obits[which]);
                    610:                                        n++;
                    611:                                }
                    612:                        }
                    613:                }
                    614:        }
                    615:        *retval = n;
                    616:        return (error);
                    617: }
                    618: 
                    619: /*ARGSUSED*/
1.1.1.2 ! root      620: int
1.1       root      621: seltrue(dev_t dev, int which, struct proc *p)
                    622: {
                    623: 
                    624:        return (1);
                    625: }
                    626: 
1.1.1.2 ! root      627: void
        !           628: selwakeup(pid_t pid, int coll)
1.1       root      629: {
1.1.1.2 ! root      630:        register struct proc *p;
1.1       root      631: 
                    632:        if (coll) {
                    633:                nselcoll++;
                    634:                wakeup((caddr_t)&selwait);
                    635:        }
1.1.1.2 ! root      636:        if (pid && (p = pfind(pid))) {
1.1       root      637:                int s = splhigh();
                    638:                if (p->p_wchan == (caddr_t)&selwait) {
                    639:                        if (p->p_stat == SSLEEP)
                    640:                                setrun(p);
                    641:                        else
                    642:                                unsleep(p);
                    643:                } else if (p->p_flag & SSEL)
                    644:                        p->p_flag &= ~SSEL;
                    645:                splx(s);
                    646:        }
                    647: }

unix.superglobalmegacorp.com

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