1: /* 2: * SCCS id @(#)sys2.c 2.1 (Berkeley) 9/4/83 3: */ 4: 5: #include "param.h" 6: #include <sys/systm.h> 7: #include <sys/dir.h> 8: #include <sys/user.h> 9: #include <sys/reg.h> 10: #include <sys/file.h> 11: #include <sys/inode.h> 12: #include <sys/quota.h> 13: #ifdef MENLO_JCL 14: #include <sys/proc.h> 15: #endif 16: #include <sys/inline.h> 17: 18: 19: /* 20: * read system call 21: */ 22: read() 23: { 24: rdwr(FREAD); 25: } 26: 27: /* 28: * write system call 29: */ 30: write() 31: { 32: rdwr(FWRITE); 33: } 34: 35: /* 36: * common code for read and write calls: 37: * check permissions, set base, count, and offset, 38: * and switch out to readi, writei, or pipe code. 39: */ 40: rdwr(mode) 41: register mode; 42: { 43: register struct file *fp; 44: register struct inode *ip; 45: register struct a { 46: int fdes; 47: char *cbuf; 48: unsigned count; 49: } *uap; 50: 51: uap = (struct a *)u.u_ap; 52: #ifdef UNFAST 53: if ((fp = getf(uap->fdes)) == NULL) 54: return; 55: #else 56: if (GETF(fp,uap->fdes)) { 57: u.u_error = EBADF; 58: return; 59: } 60: #endif 61: if((fp->f_flag & mode) == 0) { 62: u.u_error = EBADF; 63: return; 64: } 65: u.u_base = (caddr_t)uap->cbuf; 66: u.u_count = uap->count; 67: u.u_segflg = 0; 68: #ifdef MENLO_JCL 69: if ((u.u_procp->p_flag & SNUSIG) && save(u.u_qsav)) { 70: if (u.u_count == uap->count) 71: u.u_eosys = RESTARTSYS; 72: } else 73: #endif 74: #ifdef UCB_NET 75: if (fp->f_flag & FSOCKET) { 76: if (mode == FREAD) 77: u.u_error = soreceive(fp->f_socket, (struct sockaddr *)0); 78: else 79: u.u_error = sosend(fp->f_socket, (struct sockaddr *)0); 80: } else 81: #endif 82: if((fp->f_flag & FPIPE) != 0) { 83: if(mode == FREAD) 84: readp(fp); 85: else 86: writep(fp); 87: } else { 88: ip = fp->f_inode; 89: #ifdef MPX_FILS 90: if (fp->f_flag & FMP) 91: u.u_offset = 0; 92: else 93: #endif 94: u.u_offset = fp->f_un.f_offset; 95: if((ip->i_mode & (IFCHR & IFBLK)) == 0) 96: plock(ip); 97: if(mode == FREAD) 98: readi(ip); 99: else 100: writei(ip); 101: if((ip->i_mode & (IFCHR & IFBLK)) == 0) 102: prele(ip); 103: #ifdef MPX_FILS 104: if ((fp->f_flag & FMP) == 0) 105: #endif 106: fp->f_un.f_offset += uap->count-u.u_count; 107: } 108: u.u_r.r_val1 = uap->count-u.u_count; 109: } 110: 111: /* 112: * open system call 113: */ 114: open() 115: { 116: register struct inode *ip; 117: register struct a { 118: char *fname; 119: int rwmode; 120: } *uap; 121: 122: uap = (struct a *)u.u_ap; 123: #ifndef UCB_SYMLINKS 124: ip = namei(uchar, LOOKUP); 125: #else 126: ip = namei(uchar, LOOKUP, 1); 127: #endif 128: if(ip == NULL) 129: return; 130: open1(ip, ++uap->rwmode, 0); 131: } 132: 133: /* 134: * creat system call 135: */ 136: creat() 137: { 138: register struct inode *ip; 139: register struct a { 140: char *fname; 141: int fmode; 142: } *uap; 143: 144: uap = (struct a *)u.u_ap; 145: #ifndef UCB_SYMLINKS 146: ip = namei(uchar, CREATE); 147: #else 148: ip = namei(uchar, CREATE, 1); 149: #endif 150: if(ip == NULL) { 151: if(u.u_error) 152: return; 153: ip = maknode(uap->fmode & 07777 & (~ISVTX)); 154: if (ip==NULL) 155: return; 156: open1(ip, FWRITE, 2); 157: } else 158: open1(ip, FWRITE, 1); 159: } 160: 161: /* 162: * common code for open and creat. 163: * Check permissions, allocate an open file structure, 164: * and call the device open routine if any. 165: */ 166: open1(ip, mode, trf) 167: register struct inode *ip; 168: register mode; 169: { 170: register struct file *fp; 171: int i; 172: 173: if(trf != 2) { 174: if(mode & FREAD) 175: access(ip, IREAD); 176: if(mode & FWRITE) { 177: access(ip, IWRITE); 178: if((ip->i_mode & IFMT) == IFDIR) 179: u.u_error = EISDIR; 180: } 181: } 182: if(u.u_error) 183: goto out; 184: if(trf == 1) 185: itrunc(ip); 186: prele(ip); 187: if ((fp = falloc()) == NULL) 188: goto out; 189: fp->f_flag = mode & (FREAD|FWRITE); 190: fp->f_inode = ip; 191: i = u.u_r.r_val1; 192: openi(ip, mode & FWRITE); 193: if(u.u_error == 0) 194: return; 195: u.u_ofile[i] = NULL; 196: fp->f_count--; 197: 198: out: 199: iput(ip); 200: } 201: 202: /* 203: * close system call 204: */ 205: close() 206: { 207: register struct file *fp; 208: register struct a { 209: int fdes; 210: } *uap; 211: 212: uap = (struct a *)u.u_ap; 213: #ifdef UNFAST 214: if ((fp = getf(uap->fdes)) == NULL) 215: return; 216: #else 217: if (GETF(fp,uap->fdes)) { 218: u.u_error = EBADF; 219: return; 220: } 221: #endif 222: u.u_ofile[uap->fdes] = NULL; 223: #ifndef UCB_NET 224: closef(fp); 225: #else 226: closef(fp,0); 227: #endif 228: } 229: 230: /* 231: * seek system call 232: */ 233: seek() 234: { 235: register struct file *fp; 236: register struct a { 237: int fdes; 238: off_t off; 239: int sbase; 240: } *uap; 241: 242: uap = (struct a *)u.u_ap; 243: #ifdef UNFAST 244: if ((fp = getf(uap->fdes)) == NULL) 245: return; 246: #else 247: if (GETF(fp,uap->fdes)) { 248: u.u_error = EBADF; 249: return; 250: } 251: #endif 252: #ifdef UCB_NET 253: if (fp->f_flag&FSOCKET) { 254: u.u_error = ESPIPE; 255: return; 256: } 257: #endif 258: #ifdef MPX_FILS 259: if(fp->f_flag & (FPIPE|FMP)) 260: #else 261: if(fp->f_flag & FPIPE) 262: #endif 263: { 264: u.u_error = ESPIPE; 265: return; 266: } 267: if(uap->sbase == FSEEK_RELATIVE) 268: uap->off += fp->f_un.f_offset; 269: else if(uap->sbase == FSEEK_EOF) 270: uap->off += fp->f_inode->i_size; 271: fp->f_un.f_offset = uap->off; 272: u.u_r.r_off = uap->off; 273: } 274: 275: /* 276: * link system call 277: */ 278: link() 279: { 280: register struct inode *ip, *xp; 281: register struct a { 282: char *target; 283: char *linkname; 284: } *uap; 285: 286: uap = (struct a *)u.u_ap; 287: #ifndef UCB_SYMLINKS 288: ip = namei(uchar, LOOKUP); 289: #else 290: ip = namei(uchar, LOOKUP, 1); 291: #endif 292: if(ip == NULL) 293: return; 294: #ifdef UCB_QUOTAS 295: if (((ip->i_mode & IFMT)==IFDIR || isquot(ip)) && !suser()) 296: #else 297: if((ip->i_mode & IFMT)==IFDIR && !suser()) 298: #endif 299: goto out; 300: 301: ip->i_nlink++; 302: ip->i_flag |= ICHG; 303: #ifdef UCB_FSFIX 304: iupdat(ip, &time, &time, 1); 305: #else 306: iupdat(ip, &time, &time); 307: #endif 308: prele(ip); 309: u.u_dirp = (caddr_t)uap->linkname; 310: #ifndef UCB_SYMLINKS 311: xp = namei(uchar, CREATE); 312: #else 313: xp = namei(uchar, CREATE, 0); 314: #endif 315: if(xp != NULL) { 316: u.u_error = EEXIST; 317: iput(xp); 318: } else { 319: if (u.u_error) 320: goto err; 321: if (u.u_pdir->i_dev != ip->i_dev) { 322: iput(u.u_pdir); 323: u.u_error = EXDEV; 324: } else 325: wdir(ip); 326: } 327: 328: if (u.u_error) { 329: err: 330: ip->i_nlink--; 331: ip->i_flag |= ICHG; 332: } 333: out: 334: iput(ip); 335: } 336: 337: /* 338: * mknod system call 339: */ 340: mknod() 341: { 342: register struct inode *ip; 343: register struct a { 344: char *fname; 345: int fmode; 346: int dev; 347: } *uap; 348: 349: if(suser()) { 350: uap = (struct a *)u.u_ap; 351: #ifndef UCB_SYMLINKS 352: ip = namei(uchar, CREATE); 353: #else 354: ip = namei(uchar, CREATE, 0); 355: #endif 356: if(ip != NULL) { 357: u.u_error = EEXIST; 358: goto out; 359: } 360: ip = maknode(uap->fmode); 361: if (ip == NULL) 362: return; 363: #ifdef UCB_FSFIX 364: if (uap->dev) { 365: ip->i_un.i_rdev = (dev_t)uap->dev; 366: ip->i_flag |= IACC|IUPD|ICHG; 367: } 368: #else 369: ip->i_un.i_rdev = (dev_t)uap->dev; 370: #endif 371: out: 372: iput(ip); 373: } 374: } 375: 376: /* 377: * access system call 378: */ 379: saccess() 380: { 381: register struct inode *ip; 382: register struct a { 383: char *fname; 384: int fmode; 385: } *uap; 386: register svuid, svgid; 387: 388: uap = (struct a *)u.u_ap; 389: svuid = u.u_uid; 390: svgid = u.u_gid; 391: u.u_uid = u.u_ruid; 392: u.u_gid = u.u_rgid; 393: #ifndef UCB_SYMLINKS 394: ip = namei(uchar, LOOKUP); 395: #else 396: ip = namei(uchar, LOOKUP, 1); 397: #endif 398: if (ip != NULL) { 399: if ((uap->fmode & FACCESS_READ) && access(ip, IREAD)) 400: goto done; 401: if ((uap->fmode & FACCESS_WRITE) && access(ip, IWRITE)) 402: goto done; 403: if ((uap->fmode & FACCESS_EXECUTE) && access(ip, IEXEC)) 404: goto done; 405: done: 406: iput(ip); 407: } 408: u.u_uid = svuid; 409: u.u_gid = svgid; 410: }