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

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

unix.superglobalmegacorp.com

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