Annotation of coherent/d/286_KERNEL/USRSRC/coh/sys3.c, revision 1.1.1.1

1.1       root        1: /* $Header: /newbits/286_KERNEL/USRSRC/coh/RCS/sys3.c,v 1.1 92/01/09 13:29: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 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:  * $Log:       sys3.c,v $
                     20:  * Revision 1.1  92/01/09  13:29:29  bin
                     21:  * Initial revision
                     22:  * 
                     23:  * Revision 1.3        89/02/07  18:50:27      src
                     24:  * Bug:        Console driver did not validate user addresses before initiating a
                     25:  *     transfer.  This resulted in a system trap in protected mode if a write
                     26:  *     outside of user data space was attempted.
                     27:  * Fix:        Reads and writes now validate user addresses via 'useracc' prior to
                     28:  *     calling drivers. (ABC)
                     29:  * 
                     30:  * Revision 1.2        88/08/02  15:01:04      src
                     31:  * O_APPEND flag now supported on open/fcntl system calls.
                     32:  * 
                     33:  * Revision 1.1        88/03/24  16:14:35      src
                     34:  * Initial revision
                     35:  * 
                     36:  * 88/01/22    Allan Cornish           /usr/src/sys/coh/sys3.c
                     37:  * sysio() inode lock extended to cover getting/modifying file seek offset.
                     38:  *
                     39:  * 86/11/19    Allan Cornish           /usr/src/sys/coh/sys3.c
                     40:  * uopen() now checks mode for O_NDELAY and sets IPNDLY bit in fdp->f_flag.
                     41:  * sysio() now checks fdp->f_flag for IPNDLY and sets IONDLY bit in io_flag.
                     42:  */
                     43: #include <sys/coherent.h>
                     44: #include <sys/buf.h>
                     45: #include <errno.h>
                     46: #include <sys/fcntl.h>
                     47: #include <sys/fd.h>
                     48: #include <sys/filsys.h>
                     49: #include <sys/ino.h>
                     50: #include <sys/inode.h>
                     51: #include <sys/io.h>
                     52: #include <sys/mount.h>
                     53: #include <sys/stat.h>
                     54: #include <sys/uproc.h>
                     55: 
                     56: /*
                     57:  * Open the file `np' with the mode `mode'.
                     58:  */
                     59: uopen(np, mode)
                     60: char *np;
                     61: {
                     62:        register int f;
                     63:        register INODE *ip;
                     64:        register int fd;
                     65: 
                     66:        switch (mode & 3) {
                     67:        case O_RDONLY:
                     68:                f = IPR;
                     69:                break;
                     70:        case O_WRONLY:
                     71:                f = IPW;
                     72:                break;
                     73:        case O_RDWR:
                     74:                f = IPR|IPW;
                     75:                break;
                     76:        default:
                     77:                u.u_error = EINVAL;
                     78:                return;
                     79:        }
                     80:        if (ftoi(np, 'r') != 0)
                     81:                return;
                     82:        ip = u.u_cdiri;
                     83:        if (iaccess(ip, f) == 0) {
                     84:                idetach(ip);
                     85:                return;
                     86:        }
                     87:        if ( mode & O_NDELAY )
                     88:                f |= IPNDLY;
                     89:        if ( mode & O_APPEND )
                     90:                f |= IPAPPEND;
                     91:        if ((fd=fdopen(ip, f)) < 0) {
                     92:                idetach(ip);
                     93:                return;
                     94:        }
                     95:        iunlock(ip);
                     96:        return (fd);
                     97: }
                     98: 
                     99: /*
                    100:  * Create a pipe.
                    101:  */
                    102: upipe(fdp)
                    103: int fdp[2];
                    104: {
                    105:        register INODE *ip;
                    106:        register int fd1;
                    107:        register int fd2;
                    108: 
                    109:        if ((ip=pmake(0)) == NULL)
                    110:                return;
                    111:        if ((fd1=fdopen(ip, IPR)) >= 0) {
                    112:                ip->i_refc++;
                    113:                if ((fd2=fdopen(ip, IPW)) >= 0) {
                    114:                        putuwd(&fdp[0], fd1);
                    115:                        putuwd(&fdp[1], fd2);
                    116:                        iunlock(ip);
                    117:                        return (0);
                    118:                }
                    119:                --ip->i_refc;
                    120:                iunlock(ip);
                    121:                fdclose(fd1);
                    122:                return (0);
                    123:        }
                    124:        idetach(ip);
                    125:        return (0);
                    126: }
                    127: 
                    128: /*
                    129:  * Read `n' bytes into the buffer `bp' from file number `fd'.
                    130:  */
                    131: uread(fd, bp, n)
                    132: char *bp;
                    133: unsigned n;
                    134: {
                    135:        return (sysio(fd, bp, n, 0));
                    136: }
                    137: 
                    138: /*
                    139:  * Read or write `n' bytes from the file number `fd' using the buffer
                    140:  * `bp'.  If `f' is 0, we read, else write.
                    141:  */
                    142: sysio(fd, bp, n, f)
                    143: char *bp;
                    144: unsigned n;
                    145: {
                    146:        register FD *fdp;
                    147:        register INODE *ip;
                    148:        register int type;
                    149: 
                    150:        if ((fdp=fdget(fd)) == NULL)
                    151:                return (0);
                    152:        if ((fdp->f_flag&(f?IPW:IPR)) == 0) {
                    153:                u.u_error = EBADF;
                    154:                return (0);
                    155:        }
                    156:        if ( ! useracc( bp, n ) ) {
                    157:                u.u_error = EFAULT;
                    158:                return(0);
                    159:        }
                    160: 
                    161:        ip = fdp->f_ip;
                    162:        type = ip->i_mode&IFMT;
                    163:        if (type != IFCHR)
                    164:                ilock(ip);
                    165:        if ( fdp->f_flag & IPAPPEND )
                    166:                fdp->f_seek = ip->i_size;
                    167:        u.u_io.io_seek = fdp->f_seek;
                    168:        u.u_io.io_base = bp;
                    169:        u.u_io.io_ioc  = n;
                    170:        u.u_io.io_flag = (fdp->f_flag & IPNDLY) ? IONDLY : 0;
                    171:        if (f == 0) {
                    172:                iread(ip, &u.u_io);
                    173:                iacc(ip);               /* read - atime */
                    174:        } else {
                    175:                iwrite(ip, &u.u_io);
                    176:        }
                    177:        n -= u.u_io.io_ioc;
                    178:        fdp->f_seek += n;
                    179:        if (type != IFCHR)
                    180:                iunlock(ip);
                    181:        return (n);
                    182: }
                    183: 
                    184: /*
                    185:  * Return a status structure for the given file name.
                    186:  */
                    187: ustat(np, stp)
                    188: char *np;
                    189: struct stat *stp;
                    190: {
                    191:        register INODE *ip;
                    192:        struct stat stat;
                    193: 
                    194:        if (ftoi(np, 'r') != 0)
                    195:                return;
                    196:        ip = u.u_cdiri;
                    197:        istat(ip, &stat);
                    198:        idetach(ip);
                    199:        kucopy(&stat, stp, sizeof(stat));
                    200:        return (0);
                    201: }
                    202: 
                    203: /*
                    204:  * Write out all modified buffers, inodes and super blocks to disk.
                    205:  */
                    206: usync()
                    207: {
                    208:        register MOUNT *mp;
                    209:        static GATE syngate;
                    210: 
                    211:        lock(syngate);
                    212:        for (mp=mountp; mp!=NULL; mp=mp->m_next)
                    213:                msync(mp);
                    214:        bsync();
                    215:        unlock(syngate);
                    216:        return (0);
                    217: }
                    218: 
                    219: /*
                    220:  * Set the mask for file access.
                    221:  */
                    222: uumask(mask)
                    223: {
                    224:        register int omask;
                    225: 
                    226:        omask = u.u_umask;
                    227:        u.u_umask = mask & 0777;
                    228:        return (omask);
                    229: }
                    230: 
                    231: /*
                    232:  * Unmount the given device.
                    233:  */
                    234: uumount(sp)
                    235: char *sp;
                    236: {
                    237:        register INODE *ip;
                    238:        register MOUNT *mp;
                    239:        register MOUNT **mpp;
                    240:        register dev_t rdev;
                    241:        register int mode;
                    242: 
                    243:        if (ftoi(sp, 'r') != 0)
                    244:                return;
                    245:        ip = u.u_cdiri;
                    246:        if (iaccess(ip, IPR|IPW) == 0) {
                    247:                idetach(ip);
                    248:                return;
                    249:        }
                    250:        rdev = ip->i_a.i_rdev;
                    251:        mode = ip->i_mode;
                    252:        idetach(ip);
                    253:        if ((mode&IFMT) != IFBLK) {
                    254:                u.u_error = ENOTBLK;
                    255:                return;
                    256:        }
                    257:        for (mpp=&mountp; (mp=*mpp)!=NULL; mpp=&mp->m_next)
                    258:                if (mp->m_dev == rdev)
                    259:                        break;
                    260:        if (mp == NULL) {
                    261:                u.u_error = EINVAL;
                    262:                return;
                    263:        }
                    264:        msync(mp);
                    265:        for (ip=&inodep[NINODE-1]; ip>=inodep; --ip) {
                    266:                if (ip->i_refc>0 && ip->i_dev==rdev) {
                    267:                        u.u_error = EBUSY;
                    268:                        return;
                    269:                }
                    270:        }
                    271:        for (ip=&inodep[NINODE-1]; ip>=inodep; --ip) {
                    272:                if (ip->i_dev == rdev)
                    273:                        ip->i_ino = 0;
                    274:        }
                    275:        bflush(rdev);
                    276:        dclose(rdev);
                    277:        *mpp = mp->m_next;
                    278:        mp->m_ip->i_flag &= ~IFMNT;
                    279:        ldetach(mp->m_ip);
                    280:        kfree(mp);
                    281:        return (0);
                    282: }
                    283: 
                    284: /*
                    285:  * Return an unique number.
                    286:  */
                    287: long
                    288: uunique()
                    289: {
                    290:        register MOUNT *mp;
                    291:        register struct filsys *fsp;
                    292: 
                    293:        if ((mp=getment(rootdev, 1)) == NULL)
                    294:                return;
                    295:        fsp = &mp->m_super;
                    296:        fsp->s_fmod = 1;
                    297:        return (++fsp->s_unique);
                    298: }
                    299: 
                    300: /*
                    301:  * Unlink the given file.
                    302:  */
                    303: uunlink(np)
                    304: char *np;
                    305: {
                    306:        register INODE *ip;
                    307:        register dev_t dev;
                    308: 
                    309:        if (ftoi(np, 'u') != 0)
                    310:                return;
                    311:        ip = u.u_pdiri;
                    312:        if (iaccess(ip, IPW) == 0) {
                    313:                u.u_error = EACCES;
                    314:                goto err;
                    315:        }
                    316:        dev = ip->i_dev;
                    317:        if (iucheck(dev, u.u_cdirn) == 0)
                    318:                goto err;
                    319:        idirent(0);
                    320:        idetach(ip);
                    321:        if ((ip=iattach(dev, u.u_cdirn)) == NULL)
                    322:                return;
                    323:        if (ip->i_nlink > 0)
                    324:                --ip->i_nlink;
                    325:        icrt(ip);       /* unlink - ctime */
                    326:        if ((ip->i_mode&IFMT)==IFPIPE && ip->i_nlink==0 && ip->i_refc==2)
                    327:                pevent(ip);
                    328: err:
                    329:        idetach(ip);
                    330:        return (0);
                    331: }
                    332: 
                    333: /*
                    334:  * Set file times.
                    335:  */
                    336: uutime(np, utime)
                    337: char *np;
                    338: time_t utime[2];
                    339: {
                    340:        register INODE *ip;
                    341:        time_t stime[2];
                    342: 
                    343:        if (ftoi(np, 'r') != 0)
                    344:                return;
                    345:        ip = u.u_cdiri;
                    346:        if (owner(ip->i_uid)) {
                    347:                iamc(ip);       /* utime - atime/mtime/ctime */
                    348:                if (utime != NULL) {
                    349:                        ukcopy(utime, stime, sizeof(time_t[2]));
                    350:                        ip->i_atime = stime[0];
                    351:                        ip->i_mtime = stime[1];
                    352:                }
                    353:        }
                    354:        idetach(ip);
                    355:        return (0);
                    356: }
                    357: 
                    358: /*
                    359:  * Write `n' bytes from buffer `bp' on file number `fd'.
                    360:  */
                    361: uwrite(fd, bp, n)
                    362: char *bp;
                    363: unsigned n;
                    364: {
                    365:        return (sysio(fd, bp, n, 1));
                    366: }
                    367: 
                    368: /**
                    369:  *
                    370:  * int
                    371:  * useracc( base, count, mode )        -- determine user accessibility
                    372:  * caddr_t base;
                    373:  * int count;
                    374:  * int mode;
                    375:  *
                    376:  *     Input:  base  = offset in user data space of the region to be accessed.
                    377:  *             count = size of access region in bytes.
                    378:  *             mode  = access mode desired [B_READ or B_WRITE].
                    379:  *
                    380:  *     Action: Verify user has desired access mode into specified region.
                    381:  *
                    382:  *     Return: 0 = permission denied.
                    383:  *             1 = access allowed.
                    384:  *
                    385:  *     Notes:  Mode is ignored for now, but is required for compatibility
                    386:  *             with System V, and future protected mode extensions.
                    387:  */
                    388: 
                    389: int
                    390: useracc( base, count, mode )
                    391: register char * base;
                    392: int count;
                    393: int mode;
                    394: {
                    395:        register char * end;
                    396:        extern char * udl;
                    397: 
                    398:        if ( (count == 0) && (base <= udl) )
                    399:                return( 1 );
                    400: 
                    401:        /*
                    402:         * Compute address of last byte to be accessed.
                    403:         */
                    404:        end = base + count - 1;
                    405: 
                    406:        /*
                    407:         * Address has wrapped, or is past legal limit.
                    408:         */
                    409:        if ( (end < base) || (end > udl) )
                    410:                return( 0 );
                    411: 
                    412:        return( 1 );
                    413: }
                    414: 
                    415: 

unix.superglobalmegacorp.com

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