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