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