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

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

unix.superglobalmegacorp.com

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