Annotation of coherent/b/kernel/coh.386/sys2.c, revision 1.1.1.1

1.1       root        1: /* $Header: /src386/kernel/coh.386/RCS/sys2.c,v 1.11 93/06/14 13:35:29 bin Exp Locker: bin $ */
                      2: /* (lgl-
                      3:  *     The information contained herein is a trade secret of Mark Williams
                      4:  *     Company, and  is confidential information.  It is provided  under a
                      5:  *     license agreement,  and may be  copied or disclosed  only under the
                      6:  *     terms of  that agreement.  Any  reproduction or disclosure  of this
                      7:  *     material without the express written authorization of Mark Williams
                      8:  *     Company or pursuant to the license agreement is unlawful.
                      9:  *
                     10:  *     COHERENT Version 4.0
                     11:  *     Copyright (c) 1982, 1993.
                     12:  *     All rights reserved.
                     13:  -lgl) */
                     14: /*
                     15:  * Coherent.
                     16:  * System calls (filesystem related).
                     17:  */
                     18: #include <sys/coherent.h>
                     19: #include <errno.h>
                     20: #include <fcntl.h>
                     21: #include <sys/fd.h>
                     22: #include <sys/ino.h>
                     23: #include <sys/inode.h>
                     24: #include <sys/mount.h>
                     25: #include <sys/sched.h>
                     26: #include <sys/stat.h>
                     27: 
                     28: /*
                     29:  * Determine accessibility of the given file.
                     30:  */
                     31: uaccess(np, mode)
                     32: char *np;
                     33: register int mode;
                     34: {
                     35:        register INODE *ip;
                     36:        register int r;
                     37: 
                     38:        schizo();
                     39:        r = ftoi(np, 'r');
                     40:        schizo();
                     41:        if (r)
                     42:                return;
                     43:        ip = u.u_cdiri;
                     44:        if ((mode&imode(ip, u.u_ruid, u.u_rgid)) != mode)
                     45:                u.u_error = EACCES;
                     46:        idetach(ip);
                     47:        return 0;
                     48: }
                     49: 
                     50: /*
                     51:  * Schizo - swap real and effective id's.
                     52:  */
                     53: schizo()
                     54: {
                     55:        register int t;
                     56: 
                     57:        t = u.u_uid;
                     58:        u.u_uid = u.u_ruid;
                     59:        u.u_ruid = t;
                     60:        t = u.u_gid;
                     61:        u.u_gid = u.u_rgid;
                     62:        u.u_rgid = t;
                     63: }
                     64: 
                     65: /*
                     66:  * Turn accounting on or off.
                     67:  */
                     68: uacct(np)
                     69: register char *np;
                     70: {
                     71:        register INODE *ip;
                     72: 
                     73:        if (super() == 0)
                     74:                return;
                     75:        if (np == NULL) {
                     76:                if (acctip == NULL) {
                     77:                        u.u_error = EINVAL;
                     78:                        return;
                     79:                }
                     80:                ldetach(acctip);
                     81:                acctip = NULL;
                     82:        } else {
                     83:                if (acctip != NULL) {
                     84:                        u.u_error = EINVAL;
                     85:                        return;
                     86:                }
                     87:                if (ftoi(np, 'r'))
                     88:                        return;
                     89:                ip = u.u_cdiri;
                     90:                if ((ip->i_mode&IFMT) != IFREG) {
                     91:                        u.u_error = EINVAL;
                     92:                        idetach(ip);
                     93:                        return;
                     94:                }
                     95:                iunlock(ip);
                     96:                acctip = ip;
                     97:        }
                     98:        return 0;
                     99: }
                    100: 
                    101: /*
                    102:  * Set current directory.
                    103:  */
                    104: uchdir(np)
                    105: char *np;
                    106: {
                    107:        setcdir(np, &u.u_cdir);
                    108:        return 0;
                    109: }
                    110: 
                    111: /*
                    112:  * Given a directory name and a pointer to a working directory pointer,
                    113:  * Save the inode associated with the directory name in the working
                    114:  * directory pointer and release the old one.  This is used to change
                    115:  * working and root directories.
                    116:  */
                    117: setcdir(np, ipp)
                    118: char *np;
                    119: register INODE **ipp;
                    120: {
                    121:        register INODE *ip;
                    122: 
                    123:        if (ftoi(np, 'r'))
                    124:                return;
                    125:        ip = u.u_cdiri;
                    126:        if ((ip->i_mode&IFMT) != IFDIR) {
                    127:                u.u_error = ENOTDIR;
                    128:                idetach(ip);
                    129:                return;
                    130:        }
                    131:        if (iaccess(ip, IPE) == 0) {
                    132:                u.u_error = EACCES;
                    133:                idetach(ip);
                    134:                return;
                    135:        }
                    136:        iunlock(ip);
                    137:        ldetach(*ipp);
                    138:        *ipp = ip;
                    139: }
                    140: 
                    141: /*
                    142:  * Change the mode of a file.
                    143:  */
                    144: uchmod(np, mode)
                    145: char *np;
                    146: {
                    147:        register INODE *ip;
                    148: 
                    149:        if (ftoi(np, 'r'))
                    150:                return;
                    151:        ip = u.u_cdiri;
                    152:        if (owner(ip->i_uid)) {
                    153:                if (u.u_uid)
                    154:                        mode &= ~ISVTXT;
                    155:                ip->i_mode &= IFMT;
                    156:                ip->i_mode |= mode&~IFMT;
                    157:                icrt(ip);       /* chmod - ctime */
                    158:        }
                    159:        idetach(ip);
                    160:        return 0;
                    161: }
                    162: 
                    163: /*
                    164:  * Change owner and group of a file.
                    165:  */
                    166: uchown(np, uid, gid)
                    167: char *np;
                    168: {
                    169:        register INODE *ip;
                    170: 
                    171:        if (ftoi(np, 'r'))
                    172:                return;
                    173:        ip = u.u_cdiri;
                    174:        if (super()) {
                    175:                ip->i_mode &= ~(ISUID | ISGID);  /* clear any setuid/setgid */
                    176:                ip->i_uid = uid;
                    177:                ip->i_gid = gid;
                    178:                icrt(ip);       /* chown - ctime */
                    179:        }
                    180:        idetach(ip);
                    181:        return 0;
                    182: }
                    183: 
                    184: /*
                    185:  * Set root directory.
                    186:  */
                    187: uchroot(np)
                    188: register char *np;
                    189: {
                    190:        if (super())
                    191:                setcdir(np, &u.u_rdir);
                    192:        return 0;
                    193: }
                    194: 
                    195: /*
                    196:  * Close the given file descriptor.
                    197:  */
                    198: uclose(fd)
                    199: {
                    200:        fdclose(fd);
                    201:        return 0;
                    202: }
                    203: 
                    204: /*
                    205:  * Create a file with the given mode.
                    206:  */
                    207: ucreat(np, mode)
                    208: char *np;
                    209: register int mode;
                    210: {
                    211:        return(uopen(np, O_WRONLY|O_CREAT|O_TRUNC, mode));
                    212: }
                    213: 
                    214: /*
                    215:  * Duplicate a file descriptor.
                    216:  */
                    217: udup(ofd)
                    218: {
                    219:        return ufcntl(ofd, F_DUPFD, 0);
                    220: }
                    221: 
                    222: /*
                    223:  * Given a file descriptor, return a status structure.
                    224:  */
                    225: ufstat(fd, stp)
                    226: struct stat *stp;
                    227: {
                    228:        register INODE *ip;
                    229:        register FD *fdp;
                    230:        struct stat stat;
                    231: 
                    232:        if ((fdp=fdget(fd)) == NULL)
                    233:                return;
                    234:        ip = fdp->f_ip;
                    235:        istat(ip, &stat);
                    236:        kucopy(&stat, stp, sizeof(stat));
                    237:        return 0;
                    238: }
                    239: 
                    240: /*
                    241:  * File control.
                    242:  */
                    243: ufcntl( fd, cmd, arg )
                    244: int fd, cmd, arg;
                    245: {
                    246:        register FD * fdp;
                    247:        FLOCK sfl;
                    248: 
                    249:        T_VLAD(2, printf("fcntl(%d,%x,%x) ", fd, cmd, arg));
                    250: 
                    251:        /*
                    252:         * Validate file descriptor.
                    253:         */
                    254:        if ( (fd < 0) || (fd >= NOFILE) || ((fdp = u.u_filep[fd]) == 0) ) {
                    255:                u.u_error = EBADF;
                    256:                return;
                    257:        }
                    258: 
                    259:        switch ( cmd ) {
                    260: 
                    261:        case F_DUPFD:
                    262:                /*
                    263:                 * Validate base file descriptor.
                    264:                 */
                    265:                if ( (arg < 0) || (arg >= NOFILE) ) {
                    266:                        u.u_error = EINVAL;
                    267:                        return;
                    268:                }
                    269: 
                    270:                /*
                    271:                 * Search for next available file descriptor.
                    272:                 */
                    273:                do {
                    274:                        if ( u.u_filep[arg] == 0 ) {
                    275:                                u.u_filep[arg] = fdp;
                    276:                                fdp->f_refc++;
                    277:                                return arg;
                    278:                        }
                    279:                } while ( ++arg < NOFILE );
                    280: 
                    281:                u.u_error = EMFILE;
                    282:                return;
                    283: 
                    284:        case F_SETFL:
                    285:                fdp->f_flag &= ~(IPNDLY|IPAPPEND);
                    286:                if ( arg & O_NDELAY )
                    287:                        fdp->f_flag |= IPNDLY;
                    288:                if ( arg & O_APPEND )
                    289:                        fdp->f_flag |= IPAPPEND;
                    290:                /* no break */
                    291: 
                    292:        case F_GETFL:
                    293:                switch ( fdp->f_flag & (IPR+IPW) ) {
                    294:                case IPR: arg = O_RDONLY; break;
                    295:                case IPW: arg = O_WRONLY; break;
                    296:                default:  arg = O_RDWR;   break;
                    297:                }
                    298:                if ( fdp->f_flag & IPNDLY )
                    299:                        arg |= O_NDELAY;
                    300:                if ( fdp->f_flag & IPAPPEND )
                    301:                        arg |= O_APPEND;
                    302:                return arg;
                    303: 
                    304:        case F_GETLK:
                    305:        case F_SETLK:
                    306:        case F_SETLKW:
                    307:                ukcopy(*(FLOCK **)&arg, &sfl, sizeof(FLOCK));
                    308:                if (u.u_error)
                    309:                        return -1;
                    310:                if (rlock(fdp, cmd, &sfl))
                    311:                        return -1;
                    312:                if (cmd == F_GETLK) {
                    313:                        kucopy(&sfl, *(FLOCK **)&arg, sizeof(FLOCK));
                    314:                        if (u.u_error)
                    315:                                return -1;
                    316:                }
                    317:                return 0;
                    318: 
                    319:        case F_GETFD:
                    320:                return fdp->f_flag2 & FD_CLOEXEC;
                    321: 
                    322:        case F_SETFD:
                    323:                if (arg & FD_CLOEXEC)
                    324:                        fdp->f_flag2 |= FD_CLOEXEC;
                    325:                else
                    326:                        fdp->f_flag2 &= ~FD_CLOEXEC;
                    327:                return 0;
                    328: 
                    329:        default:
                    330:                T_VLAD(0x02,
                    331:                  printf("'fcntl - unknown cmd=%d arg=0x0%x' ", cmd, arg));
                    332:                u.u_error = EINVAL;
                    333:        }
                    334: }
                    335: 
                    336: /*
                    337:  * Device control information.
                    338:  */
                    339: uioctl(fd, r, argp)
                    340: struct sgttyb *argp;
                    341: {
                    342:        register FD *fdp;
                    343:        register INODE *ip;
                    344:        register int mode;
                    345: 
                    346: 
                    347:        T_PIGGY( 0x8, printf("uioctl(%d, 0x%x, 0x%x)", fd, r, argp); );
                    348: 
                    349:        if ((fdp=fdget(fd)) == NULL)
                    350:                return;
                    351:        ip = fdp->f_ip;
                    352:        mode = ip->i_mode&IFMT;
                    353:        if (mode!=IFCHR && mode!=IFBLK) {
                    354:                u.u_error = ENOTTY;
                    355:                return;
                    356:        }
                    357:        dioctl(ip->i_a.i_rdev, r, argp);
                    358:        return 0;
                    359: }
                    360: 
                    361: /*
                    362:  * Create a link, `np2' to the already existing file `np1'.
                    363:  */
                    364: ulink(np1, np2)
                    365: char *np1;
                    366: char *np2;
                    367: {
                    368:        register INODE *ip1;
                    369: 
                    370:        if (ftoi(np1, 'r'))
                    371:                return;
                    372:        ip1 = u.u_cdiri;
                    373:        if ((ip1->i_mode&IFMT)==IFDIR && super()==0) {
                    374:                idetach(ip1);
                    375:                return;
                    376:        }
                    377:        iunlock(ip1);
                    378:        if (ftoi(np2, 'c')) {
                    379:                ldetach(ip1);
                    380:                return;
                    381:        }
                    382:        if (u.u_cdiri != NULL) {
                    383:                u.u_error = EEXIST;
                    384:                idetach(u.u_cdiri);
                    385:                ldetach(ip1);
                    386:                return;
                    387:        }
                    388:        if (ip1->i_dev != u.u_pdiri->i_dev) {
                    389:                u.u_error = EXDEV;
                    390:                idetach(u.u_pdiri);
                    391:                ldetach(ip1);
                    392:                return;
                    393:        }
                    394:        if (iaccess(u.u_pdiri, IPW) == 0) {
                    395:                idetach(u.u_pdiri);
                    396:                ldetach(ip1);
                    397:                return;
                    398:        }
                    399:        idirent(ip1->i_ino);
                    400:        idetach(u.u_pdiri);
                    401:        ilock(ip1);
                    402:        /* idirent() can fail during iwrite. In this case we should not 
                    403:          * increase link count. 
                    404:         * As result of this old bug, 286 mkdir utility destroys file 
                    405:         * system when runs out of free blocks.
                    406:         */
                    407:        if (!u.u_error)
                    408:                ip1->i_nlink++;
                    409:        icrt(ip1);      /* link - ctime */
                    410:        idetach(ip1);
                    411:        return 0;
                    412: }
                    413: 
                    414: /*
                    415:  * Seek on the given file descriptor.
                    416:  */
                    417: off_t
                    418: ulseek(fd, off, w)
                    419: register off_t off;
                    420: {
                    421:        register FD *fdp;
                    422:        register INODE *ip;
                    423: 
                    424:        if ((fdp=fdget(fd)) == NULL)
                    425:                return;
                    426:        ip = fdp->f_ip;
                    427:        if ((ip->i_mode&IFMT) == IFPIPE) {
                    428:                u.u_error = ESPIPE;
                    429:                return;
                    430:        }
                    431:        switch (w) {
                    432:        case 0:
                    433:                break;
                    434:        case 1:
                    435:                off += fdp->f_seek;
                    436:                break;
                    437:        case 2:
                    438:                off += ip->i_size;
                    439:                break;
                    440:        default:
                    441:                u.u_error = EINVAL;
                    442:                return;
                    443:        }
                    444: 
                    445:        if (off < 0) {
                    446:                u.u_error = EINVAL;
                    447:                return;
                    448:        }
                    449: 
                    450:        fdp->f_seek = off;
                    451:        return (off);
                    452: }
                    453: 
                    454: /*
                    455:  * Create a special file.
                    456:  */
                    457: umknod(np, mode, rdev)
                    458: char *np;
                    459: dev_t rdev;
                    460: {
                    461:        register INODE *ip;
                    462:        register int type;
                    463: 
                    464:        type = mode&IFMT;
                    465:        if (type!=IFPIPE && super()==0)
                    466:                return;
                    467:        if (type!=IFBLK && type!=IFCHR)
                    468:                rdev = 0;
                    469:        if (ftoi(np, 'c'))
                    470:                return;
                    471:        if ((ip=u.u_cdiri) != NULL) {
                    472:                u.u_error = EEXIST;
                    473:                idetach(ip);
                    474:                return;
                    475:        }
                    476:        if ((ip=imake(mode, rdev)) != NULL)
                    477:                idetach(ip);
                    478:        return 0;
                    479: }
                    480: 
                    481: /*
                    482:  * Mount the device `sp' on the pathname `np'.  The flag, `f',
                    483:  * indicates that the device is to be mounted read only.
                    484:  */
                    485: umount(sp, np, f)
                    486: char *sp;
                    487: char *np;
                    488: {
                    489:        register INODE *ip;
                    490:        register MOUNT *mp;
                    491:        register dev_t rdev;
                    492:        register int mode;
                    493: 
                    494:        if (ftoi(sp, 'r'))
                    495:                return;
                    496:        ip = u.u_cdiri;
                    497:        if (iaccess(ip, IPR|IPW) == 0)
                    498:                goto err;
                    499:        mode = ip->i_mode;
                    500:        rdev = ip->i_a.i_rdev;
                    501:        if ((mode&IFMT) != IFBLK) {
                    502:                u.u_error = ENOTBLK;
                    503:                goto err;
                    504:        }
                    505:        idetach(ip);
                    506:        if (ftoi(np, 'r'))
                    507:                return;
                    508:        ip = u.u_cdiri;
                    509:        if (iaccess(ip, IPR) == 0)
                    510:                goto err;
                    511:        if ((ip->i_mode&IFMT) != IFDIR) {
                    512:                u.u_error = ENOTDIR;
                    513:                goto err;
                    514:        }
                    515:        /* Check for current directory, open, or mount directory */
                    516:        if (ip->i_refc > 1 || ip->i_ino == ROOTIN) {
                    517:                u.u_error = EBUSY;
                    518:                goto err;
                    519:        }
                    520:        for (mp=mountp; mp!=NULL; mp=mp->m_next) {
                    521:                if (mp->m_dev == rdev) {
                    522:                        u.u_error = EBUSY;
                    523:                        goto err;
                    524:                }
                    525:        }
                    526:        if ((mp=fsmount(rdev, f)) == NULL)
                    527:                goto err;
                    528:        mp->m_ip = ip;
                    529:        ip->i_flag |= IFMNT;
                    530:        ip->i_refc++;
                    531: err:
                    532:        idetach(ip);
                    533:        return 0;
                    534: }
                    535: 
                    536: /*
                    537:  * Poll devices for input/output events.
                    538:  */
                    539: int
                    540: upoll(pollfds, npoll, msec)
                    541: struct pollfd * pollfds;
                    542: unsigned long npoll;
                    543: int msec;
                    544: {
                    545:        register struct pollfd * pollp; /* current poll pointer          */
                    546:        register FD *   fdp;            /* current file descriptor ptr   */
                    547:        auto     int    fd;             /* current file descriptor       */
                    548:        auto     int    rev;            /* last event report received    */
                    549:        auto     int    nev;            /* number non-zero event reports */
                    550:        auto     int    i;
                    551:        char * cp;
                    552:        int ret = -1;
                    553: 
                    554:        /*
                    555:         * Validate number of polls.
                    556:         */
                    557:        if ((npoll < 0) || (npoll > NOFILE)) {
                    558:                u.u_error = EINVAL;
                    559:                goto poll_done;
                    560:        }
                    561: 
                    562:        /*
                    563:         * If there are any fd's to poll
                    564:         *   validate address of polling information.
                    565:         * npoll of 0 is legal, allows user a short delay.
                    566:         */
                    567:        if (npoll)
                    568:                if ((pollfds == NULL)
                    569:                  || !useracc(pollfds, npoll*sizeof(struct pollfd), 1)) {
                    570:                        u.u_error = EFAULT;
                    571:                        goto poll_done;
                    572:                }
                    573: 
                    574:        for (;;) {
                    575:                /*
                    576:                 * Service each poll in turn.
                    577:                 */
                    578:                for (nev=0, i=npoll, pollp = pollfds; i > 0; --i, pollp++) {
                    579: 
                    580:                        /*
                    581:                         * Fetch file descriptor.
                    582:                         */
                    583:                        fd = getuwd(&pollp->fd);
                    584: 
                    585:                        /*
                    586:                         * Ignore negative file descriptors.
                    587:                         */
                    588:                        if (fd < 0) {
                    589:                                rev = 0;
                    590:                                goto remember;
                    591:                        }
                    592: 
                    593: #if 1
                    594:                        /*
                    595:                         * Ignore file descriptors that are too large.
                    596:                         */
                    597:                        if (fd >= NOFILE) {
                    598:                                rev = 0;
                    599:                                goto remember;
                    600:                        }
                    601: #else
                    602: /* For now, msg polling is deleted. */
                    603:                        /*
                    604:                         * Poll message queue.
                    605:                         */
                    606:                        if (fd >= NOFILE) {
                    607:                                rev = msgpoll(fd, getusd(&pollp->events), msec);
                    608:                                goto remember;
                    609:                        }
                    610: #endif
                    611: 
                    612:                        /*
                    613:                         * Validate file descriptor.
                    614:                         */
                    615:                        if ((fdp = u.u_filep[fd]) == 0) {
                    616:                                rev = POLLNVAL;
                    617:                                goto remember;
                    618:                        }
                    619: 
                    620:                        switch ( fdp->f_ip->i_mode & IFMT ) {
                    621:                        case IFCHR:
                    622:                                rev = dpoll(fdp->f_ip->i_a.i_rdev,
                    623:                                        getusd(&pollp->events)&0xffff, msec);
                    624:                                break;
                    625:                        case IFPIPE:
                    626:                                rev = ppoll(fdp->f_ip,
                    627:                                        getusd(&pollp->events)&0xffff, msec);
                    628:                                break;
                    629:                        default:
                    630:                                printf("polling illegal dev: fd=%d mode=%x\n",
                    631:                                        fd, fdp->f_ip->i_mode);
                    632:                                rev = POLLNVAL;
                    633:                                break;
                    634:                        }
                    635: 
                    636:                        /*
                    637:                         * Remember reponses.
                    638:                         */
                    639: remember:
                    640:                        cp = (char *)(&pollp->revents);
                    641:                        putusd(cp, rev);
                    642: 
                    643:                        /*
                    644:                         * Record number of non-zero responses.
                    645:                         */
                    646:                        if (rev)
                    647:                                nev++;
                    648:                }
                    649: 
                    650:                /*
                    651:                 * Non-blocking poll or poll response received.
                    652:                 */
                    653:                if ( (nev != 0) || (msec == 0) ) {
                    654:                        pollexit();
                    655:                        ret = nev;
                    656:                        goto poll_done;
                    657:                }
                    658: 
                    659:                /*
                    660:                 * Schedule wakeup timer if positive delay interval given
                    661:                 * and the timer is not currently set.
                    662:                 */
                    663:                if ( (msec > 0) && (cprocp->p_polltim.t_func == NULL) ) {
                    664:                        /*
                    665:                         * Convert milliseconds to clock ticks.
                    666:                         */
                    667:                        msec += (1000 / HZ) - 1;
                    668:                        msec /= (1000 / HZ);
                    669:                        timeout(&cprocp->p_polltim, msec,
                    670:                                 wakeup, &cprocp->p_polls);
                    671:                }
                    672: 
                    673:                /*
                    674:                 * Wake for polled event, poll timeout, or signal.
                    675:                 */
                    676:                x_sleep(&cprocp->p_polls, pritty, slpriSigCatch, "poll");
                    677:                /* Wakeup for polled event, poll timeout, or signal.  */
                    678: 
                    679:                /*
                    680:                 * Terminate event monitoring.
                    681:                 */
                    682:                pollexit();
                    683: 
                    684:                /*
                    685:                 * Signal woke us up.
                    686:                 */
                    687:                if (nondsig()) {
                    688:                        u.u_error = EINTR;
                    689:                        goto poll_done;
                    690:                }
                    691:                /*
                    692:                 * We were woken up by timeout wakeup.
                    693:                 */
                    694:                if ( (msec > 0) && (cprocp->p_polltim.t_lbolt <= lbolt) ) {
                    695:                        ret = 0;
                    696:                        goto poll_done;
                    697:                }
                    698:        }
                    699: 
                    700: poll_done:
                    701:        /*
                    702:         * Cancel timeout
                    703:         */
                    704:        if ( (msec > 0) && (cprocp->p_polltim.t_func != NULL) )
                    705:                timeout(&cprocp->p_polltim, 0, NULL, NULL);
                    706: 
                    707:        return ret;
                    708: }
                    709: 
                    710: /*
                    711:  * Suspend execution for a short interval.
                    712:  *
                    713:  * Return the number of milliseconds actually slept.
                    714:  * Shares use of cprocp->p_polltim with upoll().
                    715:  */
                    716: int
                    717: unap(msec)
                    718: int msec;
                    719: {
                    720:        int ret, lbolt0;
                    721:        int ticksToWait, ticksWaited;
                    722: 
                    723:        if (msec <= 0)
                    724:                return 0;
                    725: 
                    726:        /*
                    727:         * Convert milliseconds to clock ticks.
                    728:         *
                    729:         * Wait for at least the specified number of milliseconds.
                    730:         * For 100 Hz clock, if nap is for 11 msec, timeout is for 2 ticks.
                    731:         */
                    732:        ticksToWait = ((msec * HZ) + 999) / 1000;
                    733:        timeout(&cprocp->p_polltim, ticksToWait, wakeup, &cprocp->p_polls);
                    734: 
                    735:        /*
                    736:         * Wake for timeout or signal.
                    737:         */
                    738:        lbolt0 = lbolt;
                    739:        if (x_sleep(&cprocp->p_polls, pritty, slpriSigCatch, "nap")) {
                    740:                /*
                    741:                 * Signal woke us up.
                    742:                 */
                    743:                u.u_error = EINTR;
                    744:                goto napDone;
                    745:        } else {
                    746:                /*
                    747:                 * We were awakened by a timeout.
                    748:                 * Return number of milliseconds actually waited.
                    749:                 */
                    750:                ticksWaited = lbolt - lbolt0;
                    751:                if (ticksWaited >= 0)
                    752:                        ret = (ticksWaited * 1000) / HZ;
                    753:                else
                    754:                        ret = 0;
                    755:                goto napDone;
                    756:        }
                    757: 
                    758: napDone:
                    759:        /*
                    760:         * Cancel timeout
                    761:         */
                    762:        timeout(&cprocp->p_polltim, 0, NULL, NULL);
                    763: 
                    764:        return ret;
                    765: }

unix.superglobalmegacorp.com

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