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

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

unix.superglobalmegacorp.com

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