Annotation of coherent/f/tmp/sys3.c, revision 1.1.1.1

1.1       root        1: /* $Header: /src386/kernel/coh.386/RCS/sys3.c,v 1.3 93/01/18 16:21:31 bin Exp $ */
                      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 persuant to the license agreement is unlawful.
                      9:  *
                     10:  *     COHERENT Version 2.3.37
                     11:  *     Copyright (c) 1982, 1983, 1984.
                     12:  *     An unpublished work by Mark Williams Company, Chicago.
                     13:  *     All rights reserved.
                     14:  -lgl) */
                     15: /*
                     16:  * Coherent.
                     17:  * System calls (more filesystem related calls).
                     18:  */
                     19: #include <sys/coherent.h>
                     20: #include <sys/buf.h>
                     21: #include <errno.h>
                     22: #include <fcntl.h>
                     23: #include <sys/fd.h>
                     24: #include <sys/filsys.h>
                     25: #include <sys/ino.h>
                     26: #include <sys/inode.h>
                     27: #include <sys/io.h>
                     28: #include <sys/mount.h>
                     29: #include <sys/stat.h>
                     30: 
                     31: /*
                     32:  * Open the file `np' with the mode `mode'.
                     33:  */
                     34: uopen(np, oflag, magic)
                     35: char *np;
                     36: {
                     37:        register int f;
                     38:        register INODE *ip;
                     39:        register int fd;
                     40:        int cflag;      /* Flag is set if we create a file.  */
                     41: 
                     42:        cflag = 0;      /* Nothing created so far.  */
                     43: 
                     44:        /* Determine read or write status for fdopen.  */
                     45: 
                     46:        switch (oflag & 3) {
                     47:        case O_RDONLY:
                     48:                f = IPR;
                     49:                break;
                     50:        case O_WRONLY:
                     51:                f = IPW;
                     52:                break;
                     53:        case O_RDWR:
                     54:                f = IPR|IPW;
                     55:                break;
                     56:        default:
                     57:                SET_U_ERROR( EINVAL, "bad oflag" );
                     58:                T_PIGGY( 0x10000, printf("<open: bad oflag %x>", oflag); );
                     59:                return;
                     60:        }
                     61: 
                     62:        /* Process the O_CREAT flag.  */
                     63:        if ( oflag & O_CREAT ) {
                     64:                if (ftoi(np, 'c') != 0) {
                     65:                        T_PIGGY( 0x10000,
                     66:                                printf("<open: bad ftoi(%s, 'c')>", np); );
                     67:                        return;
                     68:                }
                     69: 
                     70:                /* If it didn't exist, but its parent did, then make it.  */
                     71:                if ((ip=u.u_cdiri) == NULL) {
                     72:                        if ((ip=imake((magic&~IFMT)|IFREG, 0)) == NULL) {
                     73:                                T_PIGGY( 0x10000, 
                     74:                                        printf("<open: bad imake(%x, 0)>",
                     75:                                                (magic&~IFMT)|IFREG);
                     76:                                );
                     77:                                return;
                     78:                        }
                     79:                        cflag = 1;      /* Note that we just created a file.  */
                     80:                } else {        /* The file already exists.  */
                     81:                        /*
                     82:                         * Exclusive O_CREAT on existing file should fail.
                     83:                         */
                     84:                        if ( oflag & O_EXCL ) {
                     85:                                idetach(ip);
                     86:                                SET_U_ERROR( EEXIST,
                     87:                                         "exclusive creat on existing file");
                     88:                                return;
                     89:                        }
                     90:                        /* Do not write to a read only file system;
                     91:                         * never write to a directory;
                     92:                         * always write to block and character special devices.
                     93:                         */
                     94:                        switch (ip->i_mode&IFMT) {
                     95:                        case IFBLK:
                     96:                        case IFCHR:
                     97:                                break;
                     98:                        case IFDIR:
                     99:                                idetach(ip);
                    100:                                SET_U_ERROR( EISDIR, "<open: EISDIR>" );
                    101:                                return;
                    102:                        default:
                    103:                                if (getment(ip->i_dev, 1) == NULL) {
                    104:                                        idetach(ip);
                    105:                                        SET_U_ERROR( EROFS,
                    106:                                                "Could not fetch mount entry");
                    107:                                        T_PIGGY( 0x10000,
                    108: printf("<open: bad getment(ip->i_dev: %x, 1)>", ip->i_dev); );
                    109:                                        return;
                    110:                                }
                    111:                        }
                    112:                } /* Did the file exist?  */
                    113: 
                    114:        } else { /* O_CREAT was not set--just reference the file.  */
                    115:                if (ftoi(np, 'r') != 0) {
                    116:                        T_PIGGY( 0x10000, printf("<open: bad ftoi(%s, 'r')>",
                    117:                                np);
                    118:                        );
                    119:                        return;
                    120:                }
                    121:                ip = u.u_cdiri; /* This must be the inode we wanted.  */
                    122:        }
                    123: 
                    124:        /*
                    125:         * ASSERTION: We probably have an inode for an existing file.
                    126:         * If we don't, the ip will be NULL and iaccess() will fail (as
                    127:         * desired.)
                    128:         */
                    129: 
                    130:        /*
                    131:         * Only check permissions on a pre-existing file.
                    132:         */
                    133:        if ((0 == cflag) && (iaccess(ip, f) == 0)) {
                    134:                idetach(ip);
                    135:                T_PIGGY( 0x10000,
                    136:                        printf("<open: bad access(ip:%x, f:%x)>", ip, f);
                    137:                );
                    138:                return;
                    139:        }
                    140: 
                    141:        /*
                    142:         * ASSERTION: We have an inode for a file we
                    143:         * have valid permissions on.
                    144:         */
                    145: 
                    146:        if ( ip->i_flag & IFEXCL) {
                    147:                idetach(ip);
                    148:                SET_U_ERROR( EEXIST, "open: file already open O_EXCL" );
                    149:                return; /* Somebody else has an exclusive open.  */
                    150:        }
                    151: 
                    152:        /*
                    153:         * If requesting exclusive open, fail if someone else has it open.
                    154:         */
                    155:        if ( oflag & O_EXCL ) {
                    156:                if (ip->i_refc != 1) {
                    157:                        idetach(ip);
                    158:                        SET_U_ERROR( EEXIST, "<open: O_EXCL but already open>" );
                    159:                        return;
                    160:                }
                    161: 
                    162:                /* Mark this open inode as exclusive.  */
                    163:                ip->i_flag &= IFEXCL;
                    164:        }
                    165: 
                    166:        if ( oflag & O_NDELAY ) {
                    167:                f |= IPNDLY;
                    168:        }
                    169:        if ( oflag & O_APPEND ) {
                    170:                f |= IPAPPEND;
                    171:        }
                    172:        if ( oflag & O_SYNC ) {
                    173:                f |= IPSYNC;
                    174:        }
                    175:        if ( oflag & O_EXCL ) {
                    176:                f |= IPEXCL;
                    177:        }
                    178:        if ( oflag & O_NOCTTY ) {
                    179:                f |= IPNOCTTY;
                    180:        }
                    181: 
                    182:        if ((fd=fdopen(ip, f)) < 0) {
                    183:                idetach(ip);
                    184:                T_PIGGY( 0x10000,
                    185:                        printf("<open: bad fdopen(ip: %x, f: %x>", ip, f);
                    186:                );
                    187:                return;
                    188:        }
                    189: 
                    190:        /* If requested, truncate the file.  */
                    191:        if ( oflag & O_TRUNC ) {
                    192:                if (0 == cflag) {       /* No need to truncate a new file.  */
                    193:                        if (iaccess(ip, IPW) != 0) {
                    194:                                iclear(ip);
                    195:                        } else {
                    196:                                idetach(ip);
                    197:                                T_PIGGY( 0x10000,
                    198:                                    printf("<open: No access to truncate.>");
                    199:                                );
                    200:                                return;
                    201:                        }
                    202:                }
                    203:        }
                    204: 
                    205:        iunlock(ip);
                    206:        return (fd);
                    207: }
                    208: 
                    209: /*
                    210:  * Create a pipe.  Notice, we must do the IPR fdopen with IPNDLY so that
                    211:  * we don't block waiting for the writer we are about to create.  Then
                    212:  * after we are done, we ufcntl() to turn off the IPNDLY on fd1.
                    213:  */
                    214: upipe(fdp)
                    215: short fdp[2];
                    216: {
                    217:        register INODE *ip;
                    218:        register int fd1;
                    219:        register int fd2;
                    220: 
                    221:        if ((ip=pmake(0)) == NULL)
                    222:                return;
                    223:        if ((fd1=fdopen(ip, IPR|IPNDLY)) >= 0) {
                    224:                ip->i_refc++;
                    225:                if ((fd2=fdopen(ip, IPW)) >= 0) {
                    226:                        iunlock(ip);
                    227:                        u.u_rval2 = fd2;
                    228:                        ufcntl(fd1, F_SETFL, 0);
                    229:                        return fd1;
                    230:                }
                    231:                --ip->i_refc;
                    232:                iunlock(ip);
                    233:                fdclose(fd1);
                    234:                return 0;
                    235:        }
                    236:        idetach(ip);
                    237:        return 0;
                    238: }
                    239: 
                    240: /*
                    241:  * Read `n' bytes into the buffer `bp' from file number `fd'.
                    242:  */
                    243: uread(fd, bp, n)
                    244: char *bp;
                    245: unsigned n;
                    246: {
                    247:        T_PIGGY( 0x200, printf("uread(fd: %d, bp: %x, n: %d)", fd, bp, n); );
                    248:        return (sysio(fd, bp, n, 0));
                    249: }
                    250: 
                    251: /*
                    252:  * Read or write `n' bytes from the file number `fd' using the buffer
                    253:  * `bp'.  If `do_write' is nonzero, write, else read.
                    254:  */
                    255: int
                    256: sysio(fd, bp, n, do_write)
                    257: int fd;
                    258: char *bp;
                    259: unsigned n;
                    260: int do_write;
                    261: {
                    262:        register FD *fdp;
                    263:        register INODE *ip;
                    264:        register int type;
                    265: 
                    266:        if ((fdp=fdget(fd)) == NULL)
                    267:                return 0;
                    268:        if ((fdp->f_flag&(do_write?IPW:IPR)) == 0) {
                    269:                u.u_error = EBADF;
                    270:                return 0;
                    271:        }
                    272: 
                    273:        /*
                    274:         * When reading (writing into user memory), buffer may NOT be in text
                    275:         * segment.  When writing (reading from user memory), buffer may
                    276:         * be in text segment.
                    277:         */
                    278:        if (!useracc(bp, n, !do_write)) {
                    279:                u.u_error = EFAULT;
                    280:                return 0;
                    281:        }
                    282: 
                    283:        ip = fdp->f_ip;
                    284:        type = ip->i_mode&IFMT;
                    285:        if (type != IFCHR)
                    286:                ilock(ip);
                    287:        if ( fdp->f_flag & IPAPPEND )
                    288:                fdp->f_seek = ip->i_size;
                    289:        u.u_io.io_seek = fdp->f_seek;
                    290:        u.u_io.io.vbase = (vaddr_t) bp;
                    291:        u.u_io.io_ioc  = n;
                    292:        u.u_io.io_flag = (fdp->f_flag & IPNDLY) ? IONDLY : 0;
                    293:        if (do_write) {
                    294:                iwrite(ip, &u.u_io);
                    295:        } else {
                    296:                iread(ip, &u.u_io);
                    297:                iacc(ip);               /* read - atime */
                    298:        }
                    299:        n -= u.u_io.io_ioc;
                    300:        fdp->f_seek += n;
                    301:        if (type != IFCHR)
                    302:                iunlock(ip);
                    303: 
                    304:        /* Was this inode opened for synchronous writes?  */
                    305:        if (fdp->f_flag & IPSYNC)
                    306:                isync(ip->i_dev);
                    307: 
                    308:        return n;
                    309: }
                    310: 
                    311: /*
                    312:  * Return a status structure for the given file name.
                    313:  */
                    314: ustat(np, stp)
                    315: char *np;
                    316: struct stat *stp;
                    317: {
                    318:        register INODE *ip;
                    319:        struct stat stat;
                    320: 
                    321:        if (ftoi(np, 'r') != 0)
                    322:                return;
                    323:        ip = u.u_cdiri;
                    324:        istat(ip, &stat);
                    325:        idetach(ip);
                    326:        kucopy(&stat, stp, sizeof(stat));
                    327:        return 0;
                    328: }
                    329: 
                    330: /*
                    331:  * Write out all modified buffers, inodes and super blocks to disk.
                    332:  */
                    333: usync()
                    334: {
                    335:        register MOUNT *mp;
                    336:        static GATE syngate;
                    337: 
                    338:        lock(syngate);
                    339:        for (mp=mountp; mp!=NULL; mp=mp->m_next)
                    340:                msync(mp);
                    341:        bsync();
                    342:        unlock(syngate);
                    343:        return 0;
                    344: }
                    345: 
                    346: /*
                    347:  * Set the mask for file access.
                    348:  */
                    349: uumask(mask)
                    350: {
                    351:        register int omask;
                    352: 
                    353:        omask = u.u_umask;
                    354:        u.u_umask = mask & 0777;
                    355:        return (omask);
                    356: }
                    357: 
                    358: /*
                    359:  * Unmount the given device.
                    360:  */
                    361: uumount(sp)
                    362: char *sp;
                    363: {
                    364:        register INODE *ip;
                    365:        register MOUNT *mp;
                    366:        register MOUNT **mpp;
                    367:        register dev_t rdev;
                    368:        register int mode;
                    369: 
                    370:        if (ftoi(sp, 'r') != 0)
                    371:                return;
                    372:        ip = u.u_cdiri;
                    373:        if (iaccess(ip, IPR|IPW) == 0) {
                    374:                idetach(ip);
                    375:                return;
                    376:        }
                    377:        rdev = ip->i_a.i_rdev;
                    378:        mode = ip->i_mode;
                    379:        idetach(ip);
                    380:        if ((mode&IFMT) != IFBLK) {
                    381:                u.u_error = ENOTBLK;
                    382:                return;
                    383:        }
                    384:        for (mpp=&mountp; (mp=*mpp)!=NULL; mpp=&mp->m_next)
                    385:                if (mp->m_dev == rdev)
                    386:                        break;
                    387:        if (mp == NULL) {
                    388:                u.u_error = EINVAL;
                    389:                return;
                    390:        }
                    391:        msync(mp);
                    392:        for (ip=&inodep[NINODE-1]; ip>=inodep; --ip) {
                    393:                if (ip->i_refc>0 && ip->i_dev==rdev) {
                    394:                        u.u_error = EBUSY;
                    395:                        return;
                    396:                }
                    397:        }
                    398:        for (ip=&inodep[NINODE-1]; ip>=inodep; --ip) {
                    399:                if (ip->i_dev == rdev)
                    400:                        ip->i_ino = 0;
                    401:        }
                    402:        bflush(rdev);
                    403:        dclose(rdev);
                    404:        *mpp = mp->m_next;
                    405:        mp->m_ip->i_flag &= ~IFMNT;
                    406:        ldetach(mp->m_ip);
                    407:        kfree(mp);
                    408:        return 0;
                    409: }
                    410: 
                    411: /*
                    412:  * Unlink the given file.
                    413:  */
                    414: uunlink(np)
                    415: char *np;
                    416: {
                    417:        register INODE *ip;
                    418:        register dev_t dev;
                    419: 
                    420:        if (ftoi(np, 'u') != 0)
                    421:                return;
                    422:        ip = u.u_pdiri;
                    423:        if (iaccess(ip, IPW) == 0) {
                    424:                u.u_error = EACCES;
                    425:                goto err;
                    426:        }
                    427:        dev = ip->i_dev;
                    428:        if (iucheck(dev, u.u_cdirn) == 0)
                    429:                goto err;
                    430:        idirent(0);
                    431:        idetach(ip);
                    432:        if ((ip=iattach(dev, u.u_cdirn)) == NULL)
                    433:                return;
                    434:        if (ip->i_nlink > 0)
                    435:                --ip->i_nlink;
                    436:        icrt(ip);       /* unlink - ctime */
                    437: err:
                    438:        idetach(ip);
                    439:        return 0;
                    440: }
                    441: 
                    442: /*
                    443:  * Set file times.
                    444:  */
                    445: uutime(np, utime)
                    446: char *np;
                    447: time_t utime[2];
                    448: {
                    449:        register INODE *ip;
                    450:        time_t stime[2];
                    451: 
                    452:        if (ftoi(np, 'r') != 0)
                    453:                return;
                    454:        ip = u.u_cdiri;
                    455:        if (owner(ip->i_uid)) {
                    456:                iamc(ip);       /* utime - atime/mtime/ctime */
                    457:                if (utime != NULL) {
                    458:                        ukcopy(utime, stime, sizeof(time_t[2]));
                    459:                        ip->i_atime = stime[0];
                    460:                        ip->i_mtime = stime[1];
                    461:                }
                    462:        }
                    463:        idetach(ip);
                    464:        return 0;
                    465: }
                    466: 
                    467: /*
                    468:  * Write `n' bytes from buffer `bp' on file number `fd'.
                    469:  */
                    470: uwrite(fd, bp, n)
                    471: char *bp;
                    472: unsigned n;
                    473: {
                    474:        return (sysio(fd, bp, n, 1));
                    475: }
                    476: 
                    477: /**
                    478:  *
                    479:  * int
                    480:  * useracc(base, count, writeUsr) -- determine user accessibility
                    481:  * caddr_t base;
                    482:  * int count;
                    483:  * int writeUsr;
                    484:  *
                    485:  *     Input:  base  = offset in user data space of the region to be accessed.
                    486:  *             count = size of access region in bytes.
                    487:  *             writeUsr = 0 if read access to be checked, else write
                    488:  *
                    489:  *     Action: Verify user has desired access mode into specified region.
                    490:  *
                    491:  *     Return: 0 = permission denied.
                    492:  *             1 = access allowed.
                    493:  *
                    494:  *     Notes:  Mode is ignored for now, but is required for compatibility
                    495:  *             with System V, and future protected mode extensions.
                    496:  */
                    497: int
                    498: useracc(base, count, writeUsr)
                    499: register char *base;
                    500: int writeUsr, count;
                    501: {
                    502:        int ret = 0;
                    503: 
                    504:        if (base+count >= base) {
                    505:                ret = accdata(base, count) || accstack(base, count)
                    506:                  || accShm(base, count);
                    507:                if (!writeUsr)
                    508:                        ret = ret || acctext(base, count);
                    509:        }
                    510: 
                    511:        return ret;
                    512: 
                    513:        return accdata(base, count) || accstack(base, count)
                    514:          || accShm(base, count);
                    515: }
                    516: 
                    517: /*
                    518:  * "Safe" ukcopy and kucopy - use useracc to check user address supplied.
                    519:  */
                    520: int
                    521: kucopyS(k, u, n)
                    522: {
                    523:        if (useracc(u, n, 1))
                    524:                return kucopy(k, u, n);
                    525:        else {
                    526:                u.u_error = EFAULT;
                    527:                return 0;
                    528:        }
                    529: }
                    530: 
                    531: int
                    532: ukcopyS(u, k, n)
                    533: {
                    534:        if (useracc(u, n, 0))
                    535:                return ukcopy(u, k, n);
                    536:        else {
                    537:                u.u_error = EFAULT;
                    538:                return 0;
                    539:        }
                    540: }

unix.superglobalmegacorp.com

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