|
|
1.1 ! root 1: /* sys2.c 4.7 81/04/13 */ ! 2: ! 3: #include "sys/param.h" ! 4: #include "sys/systm.h" ! 5: #include "sys/user.h" ! 6: #include "sys/file.h" ! 7: #include "sys/inode.h" ! 8: #include "sys/pte.h" ! 9: #include "sys/vm.h" ! 10: #include "sys/buf.h" ! 11: #include "sys/proc.h" ! 12: #include "sys/conf.h" ! 13: ! 14: /* ! 15: * READ AND WRITE ARE NEAR DUPLICATES OF EACH OTHER TO SAVE ! 16: * AS MUCH TIME AS POSSIBLE. ! 17: */ ! 18: ! 19: /* ! 20: * read system call ! 21: */ ! 22: read() ! 23: { ! 24: register struct file *fp; ! 25: register struct inode *ip; ! 26: register struct a { ! 27: int fdes; ! 28: char *cbuf; ! 29: unsigned count; ! 30: } *uap; ! 31: ! 32: uap = (struct a *)u.u_ap; ! 33: if ((int)uap->count < 0) { ! 34: u.u_error = EINVAL; ! 35: return; ! 36: } ! 37: if ((fp = getf(uap->fdes)) == NULL) { ! 38: u.u_error = EBADF; ! 39: return; ! 40: } ! 41: if((fp->f_flag&FREAD) == 0) { ! 42: if((fp->f_flag & FHUNGUP) == 0) /* EOF on hungup chans */ ! 43: u.u_error = EBADF; ! 44: else if (++u.u_nbadio > 64) { ! 45: if (u.u_nbadio > 128) ! 46: psignal(u.u_procp, SIGKILL); ! 47: else ! 48: psignal(u.u_procp, SIGPIPE); ! 49: } ! 50: return; ! 51: } ! 52: u.u_base = (caddr_t)uap->cbuf; ! 53: u.u_count = uap->count; ! 54: u.u_segflg = SEGUDATA; ! 55: if (setjmp(u.u_qsav)) { ! 56: if (u.u_count == uap->count) ! 57: u.u_error = EINTR; ! 58: } else { ! 59: ip = fp->f_inode; ! 60: u.u_offset = fp->f_offset; ! 61: if((ip->i_mode&(IFCHR&IFBLK)) == 0 && ip->i_sptr==NULL) { ! 62: plock(ip); ! 63: readi(ip); ! 64: prele(ip); ! 65: } else ! 66: readi(ip); ! 67: fp->f_offset = Lladd(fp->f_offset, uap->count-u.u_count); ! 68: } ! 69: u.u_r.r_val1 = uap->count-u.u_count; ! 70: } ! 71: ! 72: /* ! 73: * write system call ! 74: */ ! 75: write() ! 76: { ! 77: register struct file *fp; ! 78: register struct inode *ip; ! 79: register struct a { ! 80: int fdes; ! 81: char *cbuf; ! 82: unsigned count; ! 83: } *uap; ! 84: ! 85: uap = (struct a *)u.u_ap; ! 86: if ((int)uap->count < 0) { ! 87: u.u_error = EINVAL; ! 88: return; ! 89: } ! 90: if ((fp = getf(uap->fdes)) == NULL) { ! 91: u.u_error = EBADF; ! 92: return; ! 93: } ! 94: if((fp->f_flag&FWRITE) == 0) { ! 95: if (fp->f_flag&FHUNGUP) { ! 96: u.u_error = EPIPE; ! 97: psignal(u.u_procp, SIGPIPE); ! 98: return; ! 99: } ! 100: u.u_error = EBADF; ! 101: return; ! 102: } ! 103: u.u_base = (caddr_t)uap->cbuf; ! 104: u.u_count = uap->count; ! 105: u.u_segflg = SEGUDATA; ! 106: if (setjmp(u.u_qsav)) { ! 107: if (u.u_count == uap->count) ! 108: u.u_error = EINTR; ! 109: } else { ! 110: ip = fp->f_inode; ! 111: u.u_offset = fp->f_offset; ! 112: if((ip->i_mode&(IFCHR&IFBLK)) == 0 && ip->i_sptr==0) { ! 113: plock(ip); ! 114: writei(ip); ! 115: prele(ip); ! 116: } else ! 117: writei(ip); ! 118: fp->f_offset = Lladd(fp->f_offset, uap->count-u.u_count); ! 119: } ! 120: u.u_r.r_val1 = uap->count-u.u_count; ! 121: } ! 122: ! 123: /* ! 124: * open system call ! 125: */ ! 126: open() ! 127: { ! 128: register struct inode *ip; ! 129: register struct a { ! 130: char *fname; ! 131: int rwmode; ! 132: } *uap; ! 133: ! 134: uap = (struct a *)u.u_ap; ! 135: ip = namei(uap->fname, SEGUDATA, &nilargnamei, 1); ! 136: if(ip == NULL) ! 137: return; ! 138: open1(ip, ++uap->rwmode, 0); ! 139: } ! 140: ! 141: /* ! 142: * creat system call ! 143: */ ! 144: creat() ! 145: { ! 146: register struct inode *ip; ! 147: register struct a { ! 148: char *fname; ! 149: int fmode; ! 150: } *uap; ! 151: struct argnamei nmarg; ! 152: short mode; ! 153: ! 154: uap = (struct a *)u.u_ap; ! 155: nmarg = nilargnamei; ! 156: nmarg.flag = NI_CREAT; ! 157: nmarg.un.mode = mode = uap->fmode & 07777 & ~u.u_cmask; ! 158: ip = namei(uap->fname, SEGUDATA, &nmarg, 1); ! 159: if(ip == NULL) ! 160: return; ! 161: open1(ip, FWRITE, (nmarg.un.mode == mode)? 1: 2); ! 162: } ! 163: ! 164: /* ! 165: * common code for open and creat. ! 166: * Check permissions, allocate an open file structure, ! 167: * and call the device open routine if any. ! 168: */ ! 169: open1(ip, mode, trf) ! 170: register struct inode *ip; ! 171: register mode; ! 172: { ! 173: register struct file *fp; ! 174: int i; ! 175: ! 176: if(trf != 2) { ! 177: if(ip->i_count>1 && (ip->i_mode&ICONC)) ! 178: concurrency(ip, mode); ! 179: if(mode&FREAD) ! 180: (void) access(ip, IREAD); ! 181: if(mode&FWRITE) { ! 182: (void) access(ip, IWRITE); ! 183: if((ip->i_mode&IFMT) == IFDIR) ! 184: u.u_error = EISDIR; ! 185: } ! 186: } ! 187: if(u.u_error) ! 188: goto out; ! 189: if(trf == 1) ! 190: (*fstypsw[ip->i_fstyp]->t_trunc)(ip); ! 191: prele(ip); ! 192: if ((fp = falloc()) == NULL) ! 193: goto out; ! 194: fp->f_flag = mode&(FREAD|FWRITE); ! 195: fp->f_inode = ip; /* dubious, but see io/fd.c */ ! 196: i = u.u_r.r_val1; ! 197: if ((fp->f_inode = openi(ip, mode&(FREAD|FWRITE))) != NULL) ! 198: return; ! 199: u.u_ofile[i] = NULL; ! 200: fp->f_count--; ! 201: return; ! 202: ! 203: out: ! 204: iput(ip); ! 205: } ! 206: ! 207: ! 208: /* Mkdir system call */ ! 209: mkdir() ! 210: { ! 211: register struct a { ! 212: char *fname; ! 213: int fmode; ! 214: } *uap; ! 215: struct argnamei nmarg; ! 216: ! 217: uap = (struct a *)u.u_ap; ! 218: nmarg = nilargnamei; ! 219: nmarg.flag = NI_MKDIR; ! 220: nmarg.un.mode = (uap->fmode & 0777 & ~u.u_cmask) | IFDIR; ! 221: (void)namei(uap->fname, SEGUDATA, &nmarg, 0); ! 222: } ! 223: ! 224: /* Rmdir system call */ ! 225: rmdir() ! 226: { struct a { ! 227: char *fname; ! 228: }; ! 229: struct argnamei nmarg; ! 230: ! 231: nmarg = nilargnamei; ! 232: nmarg.flag = NI_RMDIR; ! 233: (void) namei(((struct a *)u.u_ap)->fname, SEGUDATA, &nmarg, 0); ! 234: } ! 235: ! 236: /* ! 237: * Select system call. ! 238: */ ! 239: int nselcoll; ! 240: int selwait; ! 241: ! 242: select() ! 243: { ! 244: register struct uap { ! 245: int nfd; ! 246: fd_set *rp, *wp; ! 247: int timo; ! 248: } *ap = (struct uap *)u.u_ap; ! 249: fd_set rd, wr, readable, writeable; ! 250: int nfds = 0; ! 251: time_t t = time; ! 252: int s, tsel, ncoll, rem; ! 253: unsigned len; ! 254: fd_set selscan(); ! 255: ! 256: if (ap->nfd > NOFILE) ! 257: ap->nfd = NOFILE; ! 258: if (ap->nfd < 0) { ! 259: u.u_error = EBADF; ! 260: return; ! 261: } ! 262: ! 263: /* read in only as many words as we need */ ! 264: len = ((ap->nfd+NBPW*NBBY-1)/(NBPW*NBBY))*NBPW; ! 265: if (ap->rp && copyin((caddr_t)ap->rp, (caddr_t)&rd, len)) ! 266: return; ! 267: if (ap->wp && copyin((caddr_t)ap->wp, (caddr_t)&wr, len)) ! 268: return; ! 269: retry: ! 270: ncoll = nselcoll; ! 271: u.u_procp->p_flag |= SSEL; ! 272: if (ap->rp) ! 273: readable = selscan(ap->nfd, &rd, &nfds, FREAD); ! 274: if (ap->wp) ! 275: writeable = selscan(ap->nfd, &wr, &nfds, FWRITE); ! 276: if (u.u_error) ! 277: goto done; ! 278: if (nfds) ! 279: goto done; ! 280: rem = (ap->timo+999)/1000 - (time - t); ! 281: if (ap->timo == 0 || rem <= 0) ! 282: goto done; ! 283: s = spl6(); ! 284: if ((u.u_procp->p_flag & SSEL) == 0 || nselcoll != ncoll) { ! 285: u.u_procp->p_flag &= ~SSEL; ! 286: splx(s); ! 287: goto retry; ! 288: } ! 289: u.u_procp->p_flag &= ~SSEL; ! 290: tsel = tsleep((caddr_t)&selwait, PZERO+1, rem); ! 291: splx(s); ! 292: switch (tsel) { ! 293: ! 294: case TS_OK: ! 295: goto retry; ! 296: ! 297: case TS_SIG: ! 298: u.u_error = EINTR; ! 299: return; ! 300: ! 301: case TS_TIME: ! 302: break; ! 303: } ! 304: done: ! 305: u.u_r.r_val1 = nfds; ! 306: if (ap->rp) ! 307: (void)copyout((caddr_t)&readable, (caddr_t)ap->rp, len); ! 308: if (ap->wp) ! 309: (void)copyout((caddr_t)&writeable, (caddr_t)ap->wp, len); ! 310: } ! 311: ! 312: fd_set ! 313: selscan(nfd, fdsp, nfdp, flag) ! 314: int nfd; ! 315: fd_set *fdsp; ! 316: int *nfdp, flag; ! 317: { ! 318: struct file *fp; ! 319: struct inode *ip; ! 320: unsigned int off, i, fd, able; ! 321: unsigned long bits; ! 322: fd_set res; ! 323: ! 324: /* loop through all words of the set */ ! 325: for (off=0; off<FDWORDS; off++) { ! 326: ! 327: /* loop once for each bit on in a word of the set */ ! 328: res.fds_bits[off] = 0; ! 329: bits = fdsp->fds_bits[off]; ! 330: while (i = ffs(bits)) { ! 331: fd = off*(NBPW*NBBY)+i-1; ! 332: if (fd >= nfd) ! 333: return res; ! 334: bits &= ~(1<<(i-1)); ! 335: fp = u.u_ofile[fd]; ! 336: if (fp == NULL) { ! 337: u.u_error = EBADF; ! 338: return res; ! 339: } ! 340: ip = fp->f_inode; ! 341: able = 1; ! 342: if (ip->i_sptr) ! 343: able = stselect(ip->i_sptr, flag, *nfdp); ! 344: if (able) { ! 345: res.fds_bits[off] |= (1<<(i-1)); ! 346: (*nfdp)++; ! 347: } ! 348: } ! 349: } ! 350: return res; ! 351: } ! 352: ! 353: selwakeup(p, coll) ! 354: register struct proc *p; ! 355: int coll; ! 356: { ! 357: int s; ! 358: ! 359: if (coll) { ! 360: nselcoll++; ! 361: wakeup((caddr_t)&selwait); ! 362: } ! 363: if (p) { ! 364: s = spl6(); ! 365: if (p->p_wchan == (caddr_t)&selwait) ! 366: setrun(p); ! 367: else ! 368: p->p_flag &= ~SSEL; ! 369: splx(s); ! 370: } ! 371: } ! 372: ! 373: /* ! 374: * close system call ! 375: */ ! 376: close() ! 377: { ! 378: register struct file *fp; ! 379: register struct a { ! 380: int fdes; ! 381: } *uap; ! 382: ! 383: uap = (struct a *)u.u_ap; ! 384: fp = getf(uap->fdes); ! 385: if(fp == NULL) { ! 386: u.u_error = EBADF; ! 387: return; ! 388: } ! 389: u.u_ofile[uap->fdes] = NULL; ! 390: closef(fp); ! 391: } ! 392: ! 393: /* ! 394: * [l]seek system calls ! 395: */ ! 396: ! 397: lseek() ! 398: { ! 399: doseek(1); ! 400: } ! 401: ! 402: seek() ! 403: { ! 404: doseek(0); ! 405: } ! 406: ! 407: doseek(islong) ! 408: { ! 409: register struct file *fp; ! 410: register struct a { ! 411: int fdes; ! 412: off_t off; ! 413: int sbase; ! 414: } *uap1; ! 415: register struct b { ! 416: int fdes; ! 417: llong_t off; ! 418: int sbase; ! 419: } *uap2; ! 420: llong_t off; ! 421: int fdes, sbase; ! 422: ! 423: if (islong) { ! 424: uap2 = (struct b *)u.u_ap; ! 425: fdes = uap2->fdes; ! 426: off = uap2->off; ! 427: sbase = uap2->sbase; ! 428: } else { ! 429: uap1 = (struct a *)u.u_ap; ! 430: fdes = uap1->fdes; ! 431: sbase = uap1->sbase; ! 432: off = ltoL(uap1->off); ! 433: if (sbase!=0) { /* signed offset when not w.r.t. base */ ! 434: if (uap1->off<0) ! 435: off.hi = -1; ! 436: } ! 437: } ! 438: fp = getf(fdes); ! 439: if(fp == NULL) { ! 440: u.u_error = EBADF; ! 441: return; ! 442: } ! 443: if(fp->f_inode->i_sptr) { ! 444: u.u_error = ESPIPE; ! 445: return; ! 446: } ! 447: if(sbase == 1) ! 448: off = LLadd(fp->f_offset, off); ! 449: else if(sbase == 2) ! 450: off = Lladd(off, fp->f_inode->i_size); ! 451: fp->f_offset = off; ! 452: u.u_r.r_val1 = Ltol(off); ! 453: u.u_r.r_val2 = off.hi; ! 454: } ! 455: ! 456: ! 457: /* ! 458: * link system call ! 459: */ ! 460: link() ! 461: { ! 462: register struct inode *ip; ! 463: register struct a { ! 464: char *target; ! 465: char *linkname; ! 466: } *uap; ! 467: struct argnamei nmarg; ! 468: ! 469: uap = (struct a *)u.u_ap; ! 470: ip = namei(uap->target, SEGUDATA, &nilargnamei, 0); /* well, this routine is doomed anyhow */ ! 471: if(ip == NULL) ! 472: return; ! 473: if((ip->i_mode&IFMT)==IFDIR && !suser()) ! 474: goto out1; ! 475: ip->i_nlink++; ! 476: ip->i_flag |= ICHG; ! 477: iupdat(ip, &time, &time, 1); ! 478: prele(ip); ! 479: nmarg = nilargnamei; ! 480: nmarg.flag = NI_LINK; ! 481: nmarg.un.il = ip; ! 482: (void) namei(uap->linkname, SEGUDATA, &nmarg, 0); ! 483: if(u.u_error) { ! 484: ip->i_nlink--; ! 485: ip->i_flag |= ICHG; ! 486: } ! 487: out1: ! 488: iput(ip); ! 489: } ! 490: ! 491: /* ! 492: * mknod system call ! 493: */ ! 494: mknod() ! 495: { ! 496: register struct inode *ip; ! 497: register struct a { ! 498: char *fname; ! 499: int fmode; ! 500: int dev; ! 501: } *uap; ! 502: struct argnamei nmarg; ! 503: ! 504: uap = (struct a *)u.u_ap; ! 505: if(suser()) { ! 506: nmarg = nilargnamei; ! 507: nmarg.flag = NI_NXCREAT; ! 508: nmarg.un.mode = uap->fmode & ~u.u_cmask; ! 509: ip = namei(uap->fname, SEGUDATA, &nmarg, 0); ! 510: } ! 511: if(u.u_error) ! 512: return; ! 513: if (uap->dev) { ! 514: /* ! 515: * Want to be able to use this to make badblock ! 516: * inodes, so don't truncate the dev number. ! 517: */ ! 518: ip->i_un.i_rdev = uap->dev; ! 519: ip->i_flag |= IACC|IUPD|ICHG; ! 520: } ! 521: iput(ip); ! 522: } ! 523: ! 524: /* ! 525: * access system call ! 526: */ ! 527: saccess() ! 528: { ! 529: register svuid, svgid; ! 530: register struct inode *ip; ! 531: register struct a { ! 532: char *fname; ! 533: int fmode; ! 534: } *uap; ! 535: ! 536: uap = (struct a *)u.u_ap; ! 537: svuid = u.u_uid; ! 538: svgid = u.u_gid; ! 539: u.u_uid = u.u_ruid; ! 540: u.u_gid = u.u_rgid; ! 541: ip = namei(uap->fname, SEGUDATA, &nilargnamei, 1); ! 542: if (ip != NULL) { ! 543: if (uap->fmode&(IREAD>>6)) ! 544: (void) access(ip, IREAD); ! 545: if (uap->fmode&(IWRITE>>6)) ! 546: (void) access(ip, IWRITE); ! 547: if (uap->fmode&(IEXEC>>6)) ! 548: (void) access(ip, IEXEC); ! 549: iput(ip); ! 550: } ! 551: u.u_uid = svuid; ! 552: u.u_gid = svgid; ! 553: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.