|
|
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:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.