|
|
1.1 ! root 1: #include "sys/param.h" ! 2: #include "sys/systm.h" ! 3: #include "sys/inode.h" ! 4: #include "sys/dir.h" ! 5: #include "sys/user.h" ! 6: #include "sys/psl.h" ! 7: #include "sys/stat.h" ! 8: #include "sys/buf.h" ! 9: #include "sys/pte.h" ! 10: #include "sys/cmap.h" ! 11: #include "sys/mtpr.h" ! 12: #include "sys/vmparam.h" ! 13: #include "sys/vmmac.h" ! 14: #include "sys/proc.h" ! 15: #include "sys/text.h" ! 16: #include "sys/file.h" ! 17: #include "sys/reg.h" ! 18: #include "sys/pioctl.h" ! 19: #include "sys/conf.h" ! 20: ! 21: /* I/O via /proc returns EBUSY if any of these bits are set in p_flag: */ ! 22: ! 23: #define SPRBUSY (SLOCK|SPAGE|SKEEP|SWEXIT|SPROCIO) ! 24: ! 25: #define SYSADR ((caddr_t)0x80000000) /* virtual address of system seg. */ ! 26: #define SYSP btop(0x80000000) /* virtual page no. of system seg. */ ! 27: ! 28: /* <text page no.> + P1OFF(p) == <stack page no.> of same location */ ! 29: ! 30: #define P1OFF(p) (SYSP - (p)->p_szpt*NPTEPG) ! 31: ! 32: #define TEXT 0 ! 33: #define DATA 1 ! 34: #define STACK 2 ! 35: #define USERAREA 3 ! 36: ! 37: #define min(a,b) ((a) <= (b) ? (a) : (b)) ! 38: ! 39: /* inumber to pid */ ! 40: #define PRMAGIC 64 ! 41: ! 42: #define PROCDEV (dev_t)0 ! 43: #define PRROOT 2 ! 44: ! 45: struct proc *prpidlock, *prpidwant, *pritop(); ! 46: ! 47: struct pte *Prbufmap; char *priobuf; ! 48: struct pte *Prusrmap; struct user *prusrutl; ! 49: struct pte *prclmap(); ! 50: ! 51: int prput(), prread(), prwrite(), prstat(); ! 52: int prmount(), prioctl(), prnami(); ! 53: ! 54: struct fstypsw prfs = ! 55: fsinit(prput, nulldev, prread, prwrite, nulldev, prstat, ! 56: prnami, prmount, prioctl, nullopen, nodev); ! 57: ! 58: prput(ip) ! 59: struct inode *ip; ! 60: { struct proc *p; ! 61: if(ip->i_number == PRROOT) ! 62: return; ! 63: if ((p = pritop(ip)) == NULL) ! 64: return; ! 65: p->p_trace = 0; ! 66: } ! 67: ! 68: #define SDSIZ sizeof(struct direct) ! 69: ! 70: prread(ip) ! 71: struct inode *ip; ! 72: { ! 73: static struct direct dotbuf[] = { ! 74: { PRROOT, "."}, ! 75: { PRROOT, ".."} ! 76: }; ! 77: struct direct dirbuf; ! 78: register int i, n, j; ! 79: int minproc, maxproc, modoff; ! 80: struct proc *p; ! 81: ! 82: if (ip->i_number == PRROOT) { /* fake up . .. and the proc inodes */ ! 83: if (Lsign(u.u_offset) < 0 || Ltol(u.u_offset) >= ip->i_size || ! 84: u.u_count <= 0) ! 85: return; ! 86: if (Ltol(u.u_offset) < 2*SDSIZ) { ! 87: iomove((caddr_t)dotbuf + Ltol(u.u_offset), ! 88: min(u.u_count, 2*SDSIZ - Ltol(u.u_offset)), B_READ); ! 89: if (u.u_count <= 0 || u.u_error) ! 90: return; ! 91: } ! 92: minproc = (Ltol(u.u_offset) - 2*SDSIZ)/SDSIZ; ! 93: maxproc = (Ltol(u.u_offset) + u.u_count - 1)/SDSIZ; ! 94: modoff = Ltol(u.u_offset) % SDSIZ; ! 95: for (j = 0; j < DIRSIZ; j++) ! 96: dirbuf.d_name[j] = 0; ! 97: for (i=minproc; i<min(maxproc,proccnt); i++) { ! 98: if (proc[i].p_stat == 0) ! 99: dirbuf.d_ino = 0; ! 100: else { ! 101: n = proc[i].p_pid; ! 102: dirbuf.d_ino = n + PRMAGIC; ! 103: for (j = 4; j >= 0; j--) ! 104: dirbuf.d_name[j] = n%10 + '0', n /= 10; ! 105: } ! 106: iomove((caddr_t)&dirbuf + modoff, ! 107: min(u.u_count, SDSIZ - modoff), B_READ); ! 108: if (u.u_count <= 0 || u.u_error) ! 109: return; ! 110: modoff = 0; ! 111: } ! 112: } else if ((p = pritop(ip)) != NULL) { ! 113: if (prlock(p)) ! 114: return; ! 115: prusrio(p, B_READ); ! 116: prunlock(p); ! 117: } ! 118: } ! 119: ! 120: prwrite(ip) ! 121: struct inode *ip; ! 122: { ! 123: register struct proc *p; ! 124: if (ip->i_number == PRROOT) { ! 125: u.u_error = EISDIR; ! 126: } else if ((p = pritop(ip)) != NULL) { ! 127: if (prlock(p)) ! 128: return; ! 129: prusrio(p, B_WRITE); ! 130: prunlock(p); ! 131: } ! 132: } ! 133: ! 134: prstat(ip, ub) ! 135: struct inode *ip; ! 136: struct stat *ub; ! 137: { struct stat ds; struct proc *p = (struct proc *)0; ! 138: if(ip->i_number == PRROOT || (p = pritop(ip)) != NULL) { ! 139: ds.st_dev = -1; /* who knows */ ! 140: ds.st_ino = ip->i_number; ! 141: ds.st_mode = ip->i_mode; ! 142: ds.st_nlink = ip->i_nlink; ! 143: ds.st_uid = ip->i_uid; ! 144: ds.st_gid = ip->i_gid; ! 145: ds.st_rdev = -1; ! 146: if (p) ip->i_size = ! 147: (int)ptob(p->p_tsize+p->p_dsize+p->p_ssize+UPAGES); ! 148: ds.st_size = ip->i_size; ! 149: ds.st_atime = ds.st_mtime = ds.st_ctime = time; ! 150: if(copyout((caddr_t)&ds, (caddr_t)ub, sizeof(ds)) < 0) ! 151: u.u_error = EFAULT; ! 152: } ! 153: } ! 154: ! 155: prnami(p, flagp, follow) ! 156: register struct nx *p; ! 157: struct argnamei *flagp; ! 158: { ! 159: register struct inode *dp; ! 160: register char *cp; ! 161: register int n; ! 162: ! 163: cp = p->cp; ! 164: dp = p->dp; ! 165: if ((dp->i_mode & IFMT) != IFDIR) { ! 166: u.u_error = ENOTDIR; ! 167: goto error; ! 168: } ! 169: if (access(dp, IEXEC)) ! 170: goto error; ! 171: if (flagp->flag != NI_SEARCH) { ! 172: u.u_error = EACCES; ! 173: goto error; ! 174: } ! 175: rootloop: ! 176: if (cp[0] == 0) /* "" == root */ ! 177: return (0); ! 178: if (cp[0] == '.') { ! 179: if (cp[1] == 0) /* "." */ ! 180: return (0); ! 181: if (cp[1] == '/') { /* "./" ... */ ! 182: cp += 2; ! 183: p->cp = cp; ! 184: goto rootloop; ! 185: } ! 186: if (cp[1] == '.' && (cp[2] == 0 || cp[2] == '/')) { /* ".." */ ! 187: p->dp = dp->i_mpoint; ! 188: iput(dp); ! 189: plock(p->dp); ! 190: p->dp->i_count++; ! 191: return (1); /* cp still points to ".." */ ! 192: } ! 193: u.u_error = ENOENT; /* ".somethingelse" */ ! 194: goto error; ! 195: } ! 196: n = 0; ! 197: while (*cp >= '0' && *cp <= '9') { ! 198: n *= 10; ! 199: n += *cp++ - '0'; ! 200: } ! 201: if (*cp) { /* non-digit, or /proc/123/... */ ! 202: u.u_error = ENOENT; ! 203: goto error; ! 204: } ! 205: p->dp = iget(dp, PROCDEV, n + PRMAGIC); ! 206: if (p->dp == NULL) ! 207: goto error; ! 208: if (p->dp->i_count == 1 && prfillin(p->dp)) ! 209: goto error; ! 210: iput(dp); ! 211: return (0); ! 212: ! 213: error: ! 214: p->dp = NULL; ! 215: iput(dp); ! 216: return (0); ! 217: } ! 218: ! 219: prfillin(ip) ! 220: register struct inode *ip; ! 221: { ! 222: register struct proc *p; ! 223: register int n; ! 224: ! 225: ip->i_un.i_proc = NULL; /* safety */ ! 226: n = ip->i_number - PRMAGIC; ! 227: for (p = proc; p < procNPROC; p++) ! 228: if (p->p_stat && p->p_pid == n) ! 229: break; ! 230: if (p == procNPROC || p->p_stat == SZOMB || p->p_trace) { ! 231: iput(ip); ! 232: u.u_error = ENOENT; ! 233: return (1); ! 234: } ! 235: p->p_trace = ip; ! 236: if (p->p_textp && p->p_textp->x_iptr && access(p->p_textp->x_iptr, IREAD)) ! 237: ip->i_mode = IFREG; /* regular, no permissions */ ! 238: else ! 239: ip->i_mode = IFREG | 0600; /* regular, r/w only by owner */ ! 240: ip->i_nlink = 1; ! 241: ip->i_uid = p->p_uid; ! 242: ip->i_gid = 1; /* who cares */ ! 243: ip->i_size = (int)ptob(p->p_tsize+p->p_dsize+p->p_ssize+UPAGES); ! 244: ip->i_un.i_proc = p; ! 245: ip->i_un.i_sigmask = 0; /* signal trace mask */ ! 246: return (0); ! 247: } ! 248: ! 249: prmount(sip, ip, flag, mnt, fstyp) ! 250: struct inode *sip, *ip; ! 251: { ! 252: if (!suser()) ! 253: return; ! 254: if (mnt) ! 255: pron(sip, ip, flag, fstyp); ! 256: else ! 257: proff(ip, fstyp); ! 258: } ! 259: ! 260: pron(sip, ip, flag, fstyp) ! 261: struct inode *sip; ! 262: register struct inode *ip; ! 263: { ! 264: register struct inode *rip; ! 265: struct inode pi; ! 266: ! 267: if (ip->i_fstyp == fstyp) { ! 268: u.u_error = EBUSY; ! 269: return; ! 270: } ! 271: pi.i_fstyp = fstyp; ! 272: pi.i_mpoint = NULL; ! 273: if ((rip = iget(&pi, PROCDEV, (ino_t)PRROOT)) == NULL) ! 274: return; ! 275: if (rip->i_count != 1) { /* already mounted */ ! 276: iput(rip); ! 277: u.u_error = EBUSY; ! 278: return; ! 279: } ! 280: rip->i_mpoint = ip; ! 281: rip->i_mode = IFDIR|0555; ! 282: rip->i_nlink = 2; ! 283: rip->i_uid = rip->i_gid = 0; ! 284: rip->i_size = (proccnt+2) * sizeof(struct direct); ! 285: prele(rip); ! 286: ip->i_mroot = rip; ! 287: ip->i_count++; ! 288: } ! 289: ! 290: proff(mip, fstyp) ! 291: struct inode *mip; ! 292: { ! 293: struct inode *rip; ! 294: ! 295: plock(mip); ! 296: rip = mip->i_mroot; ! 297: mip->i_mroot = NULL; ! 298: iput(mip); ! 299: plock(rip); ! 300: iput(rip); ! 301: } ! 302: ! 303: /* special tracing stuff */ ! 304: prioctl(ip, cmd, cmaddr) ! 305: struct inode *ip; ! 306: caddr_t cmaddr; ! 307: { ! 308: register struct proc *p; struct text *xp; struct inode *ixp; ! 309: int n; /* mostly for integer arguments */ ! 310: ! 311: if ((p = pritop(ip)) == NULL) ! 312: return; ! 313: switch (cmd) { ! 314: default: ! 315: u.u_error = ENOTTY; ! 316: return; ! 317: ! 318: case PIOCGETPR: /* read struct proc */ ! 319: if (copyout((char *)p, cmaddr, sizeof(struct proc))) ! 320: u.u_error = EFAULT; ! 321: return; ! 322: ! 323: case PIOCOPENT: /* open text file for reading */ ! 324: if ((xp = p->p_textp) && (ixp = xp->x_iptr)) { ! 325: plock(ixp); ! 326: ixp->i_count++; ! 327: open1(ixp, FREAD, 0); /* fairly magic linkage */ ! 328: } else ! 329: u.u_error = ENOENT; ! 330: return; ! 331: ! 332: case PIOCSTOP: /* send STOP signal and... */ ! 333: if (p->p_stat != SSTOP) ! 334: psignal(p, SIGSTOP); ! 335: /* fall through */ ! 336: case PIOCWSTOP: /* wait for process to STOP */ ! 337: if (p->p_stat != SSTOP) ! 338: tsleep((caddr_t)p->p_trace, PZERO+1, 0); ! 339: if (p->p_pid != (ip->i_number - PRMAGIC) ! 340: || p->p_stat == SZOMB) ! 341: u.u_error = ENOENT; ! 342: else if (p->p_stat != SSTOP) ! 343: u.u_error = EINTR; ! 344: return; ! 345: ! 346: case PIOCRUN: /* make process runnable */ ! 347: if (p->p_stat == SSTOP) ! 348: setrun(p); ! 349: return; ! 350: ! 351: case PIOCSMASK: /* set signal trace mask */ ! 352: if (copyin(cmaddr, (caddr_t)&ip->i_un.i_sigmask, sizeof(long))) { ! 353: u.u_error = EFAULT; ! 354: return; ! 355: } ! 356: if (ip->i_un.i_sigmask) ! 357: p->p_flag |= (STRC|SPROCTR); ! 358: else ! 359: p->p_flag &= ~(STRC|SPROCTR); ! 360: return; ! 361: ! 362: case PIOCCSIG: /* clear current signal */ ! 363: p->p_cursig = 0; ! 364: return; ! 365: ! 366: case PIOCSSIG: /* set current signal */ ! 367: if (p->p_stat != SSTOP) ! 368: u.u_error = EBUSY; ! 369: else if (copyin(cmaddr, (caddr_t)&n, sizeof(n))) ! 370: u.u_error = EFAULT; ! 371: else if ((unsigned)n > NSIG) ! 372: u.u_error = EINVAL; ! 373: else ! 374: p->p_cursig = n; ! 375: return; ! 376: ! 377: case PIOCKILL: /* send signal */ ! 378: if (copyin(cmaddr, (caddr_t)&n, sizeof(n))) ! 379: u.u_error = EFAULT; ! 380: else if ((unsigned)n > NSIG) ! 381: u.u_error = EINVAL; ! 382: else ! 383: psignal(p, n); ! 384: return; ! 385: ! 386: case PIOCSEXEC: /* stop on exec */ ! 387: p->p_flag |= SSEXEC; ! 388: return; ! 389: ! 390: case PIOCREXEC: /* run on exec */ ! 391: p->p_flag &= ~SSEXEC; ! 392: return; ! 393: ! 394: case PIOCNICE: /* set nice priority */ ! 395: if (copyin(cmaddr, (caddr_t)&n, sizeof(n))) { ! 396: u.u_error = EFAULT; ! 397: return; ! 398: } ! 399: n += p->p_nice; ! 400: if (n >= 2*NZERO) ! 401: n = 2*NZERO -1; ! 402: if (n < 0) ! 403: n = 0; ! 404: if (n < p->p_nice && !suser()) ! 405: return; ! 406: p->p_nice = n; ! 407: (void) setpri(p); ! 408: return; ! 409: } ! 410: } ! 411: ! 412: /* Lock the process p. */ ! 413: ! 414: prlock(p) ! 415: register struct proc *p; ! 416: { ! 417: int s; ! 418: ! 419: if (p != u.u_procp) { ! 420: waitloop: ! 421: if (prpidlock == p) { /* wait if p has the interlock */ ! 422: prpidwant = u.u_procp; ! 423: if (tsleep((caddr_t)&prpidlock, PZERO+1, 0) == TS_SIG) ! 424: return (u.u_error = EINTR); ! 425: goto waitloop; ! 426: } ! 427: if (p->p_flag & SPAGE) { /* wait if p is paging */ ! 428: p->p_flag |= SPROCWT; ! 429: if (tsleep((caddr_t)&(p->p_stat), PZERO+1, 0) == TS_SIG) ! 430: return (u.u_error = EINTR); ! 431: goto waitloop; ! 432: } ! 433: ! 434: s = spl6(); /* keep clock out */ ! 435: ! 436: if (p->p_flag&SPRBUSY || (p->p_stat != SSLEEP && ! 437: p->p_stat != SRUN && p->p_stat != SSTOP)) { ! 438: splx(s); ! 439: return (u.u_error = EBUSY); ! 440: } ! 441: if (p->p_flag&SLOAD && p->p_stat == SRUN) ! 442: remrq(p); /* he's now invisible to swtch() */ ! 443: ! 444: /* interlock; also causes swapin, inhibits swapout, setrq, remrq */ ! 445: ! 446: p->p_flag |= SPROCIO; ! 447: ! 448: splx(s); /* now do your worst, we don't care */ ! 449: } ! 450: u.u_procp->p_flag |= SKEEP; /* if we get swapped, could deadlock */ ! 451: ! 452: while ((p->p_flag&SLOAD) == 0) { ! 453: /* sched will see SPROCIO, swap him in, and signal us */ ! 454: if (tsleep((caddr_t)&p->p_addr, PZERO+1, 0) == TS_SIG) { ! 455: prunlock(p); ! 456: return (u.u_error = EINTR); ! 457: } ! 458: } ! 459: while (prpidlock) { ! 460: prpidwant = u.u_procp; ! 461: if (tsleep((caddr_t)&prpidlock, PZERO+1, 0) == TS_SIG) { ! 462: prunlock(p); ! 463: return (u.u_error = EINTR); ! 464: } ! 465: } ! 466: prpidlock = u.u_procp; ! 467: /* now map his user area into kernel space */ ! 468: uaccess(p, Prusrmap, prusrutl); ! 469: ! 470: return (u.u_error = 0); ! 471: } ! 472: ! 473: /* Undo prlock. */ ! 474: ! 475: prunlock(p) ! 476: register struct proc *p; ! 477: { ! 478: int s; ! 479: ! 480: u.u_procp->p_flag &= ~SKEEP; ! 481: ! 482: if (p != u.u_procp) { ! 483: s = spl6(); /* keep clock out during process state change */ ! 484: p->p_flag &= ~SPROCIO; ! 485: if (p->p_flag&SLOAD && p->p_stat == SRUN) ! 486: setrq(p); /* visible again to swtch() */ ! 487: splx(s); ! 488: } ! 489: if (prpidlock == u.u_procp) { ! 490: prpidlock = 0; ! 491: if (prpidwant) { ! 492: prpidwant = 0; ! 493: wakeup((caddr_t)&prpidlock); ! 494: } ! 495: } ! 496: return 0; ! 497: } ! 498: ! 499: /* Read/write from/to process p. */ ! 500: ! 501: #define REGADR(i) ((caddr_t)(regbase + i)) ! 502: #define SEEKADR ((caddr_t)Ltol(u.u_offset)) ! 503: ! 504: prusrio(p, flag) ! 505: register struct proc *p; int flag; ! 506: { ! 507: register int *regbase; ! 508: caddr_t maxadr; int segment, resid; ! 509: ! 510: u.u_error = 0; ! 511: if ((u_long)SEEKADR >= (u_long)(maxadr = SYSADR)) ! 512: u.u_error = EIO; ! 513: else if (SEEKADR >= (caddr_t)USRSTACK) ! 514: segment = USERAREA; ! 515: else if (SEEKADR >= (maxadr = (caddr_t)USRSTACK) - (int)ptob(p->p_ssize)) ! 516: segment = STACK; ! 517: else if (SEEKADR < (maxadr = ptob(p->p_tsize))) ! 518: segment = TEXT; ! 519: else if (SEEKADR < (maxadr = ptob(p->p_tsize+p->p_dsize))) ! 520: segment = DATA; ! 521: else ! 522: u.u_error = EIO; ! 523: if (p->p_flag & SSYS && segment != USERAREA) /* too conservative? */ ! 524: u.u_error = EIO; ! 525: ! 526: if (u.u_error) return; ! 527: ! 528: if ((flag & B_READ) == 0) switch(segment) { ! 529: case TEXT: ! 530: prxdup(p); ! 531: break; ! 532: case USERAREA: ! 533: regbase = prusrutl->u_ar0; ! 534: if (SEEKADR < REGADR(AP) || ! 535: (u_long)SEEKADR >= (u_long)(maxadr = REGADR(PS+1))) ! 536: u.u_error = EIO; ! 537: else if (SEEKADR >= REGADR(PC)) ; ! 538: else if (SEEKADR < (maxadr = REGADR(FP+1))) ; ! 539: else if (SEEKADR < REGADR(R0)) ! 540: u.u_error = EIO; ! 541: else if (SEEKADR < (maxadr = REGADR(R11+1))) ; ! 542: else if (SEEKADR < REGADR(SP) || SEEKADR >= (maxadr = REGADR(SP+1))) ! 543: u.u_error = EIO; ! 544: regbase = (int *)((u_long)prusrutl + (u_long)regbase - (u_long)&u); ! 545: if ((regbase[PS]&PSL_USERSET) != PSL_USERSET || ! 546: (regbase[PS]&PSL_USERCLR) != 0) ! 547: u.u_error = EBUSY; ! 548: break; ! 549: } ! 550: ! 551: if (u.u_error) return; ! 552: ! 553: resid = u.u_count; ! 554: if ((u_long)(Ltol(u.u_offset) + u.u_count) >= (u_long)maxadr) ! 555: u.u_count = maxadr - (caddr_t)Ltol(u.u_offset); ! 556: resid -= u.u_count; ! 557: ! 558: if (segment == USERAREA) { ! 559: iomove((caddr_t)prusrutl + ((u_long)Ltol(u.u_offset) - (u_long)&u), ! 560: u.u_count, flag); ! 561: if ((flag & B_READ) == 0) { ! 562: regbase[PS] |= PSL_USERSET; ! 563: regbase[PS] &= ~PSL_USERCLR; ! 564: } ! 565: } else ! 566: priomove(p, flag); ! 567: ! 568: u.u_count += resid; ! 569: } ! 570: ! 571: /* Move data between the object process and us. */ ! 572: ! 573: priomove(p, flag) ! 574: register struct proc *p; ! 575: { ! 576: register struct pte *pte; ! 577: register clofset, clcount; ! 578: int waslocked; ! 579: ! 580: while (u.u_count > 0 && u.u_error == 0) { ! 581: pte = prclmap(p, (caddr_t)Ltol(u.u_offset), &waslocked); ! 582: clofset = Ltol(u.u_offset) & CLOFSET; ! 583: clcount = min(u.u_count, CLSIZE*NBPG - clofset); ! 584: iomove(&priobuf[clofset], clcount, flag); ! 585: prclunmap(pte, flag | waslocked); ! 586: } ! 587: } ! 588: ! 589: /* Map and lock a cluster from process into system space. */ ! 590: ! 591: struct pte * ! 592: prclmap(p, vaddr, flagp) ! 593: register struct proc *p; ! 594: register caddr_t vaddr; ! 595: int *flagp; ! 596: { ! 597: register i; ! 598: register struct pte *pte; ! 599: i = clbase(btop(vaddr)); ! 600: if (isassv(p, i)) ! 601: i -= P1OFF(p); ! 602: pte = p->p_p0br + i; ! 603: ! 604: *flagp = 0; ! 605: if (pte->pg_v) { ! 606: if (cmap[pgtocm(pte->pg_pfnum)].c_lock) ! 607: *flagp = B_PHYS; ! 608: else ! 609: mlock(pte->pg_pfnum); ! 610: } else { ! 611: p->p_flag |= SDLYU; ! 612: pagein(vaddr, prusrutl); ! 613: p->p_flag &= ~SDLYU; ! 614: if (!pte->pg_v) ! 615: panic("prclmap: pte not valid after pagein"); ! 616: } ! 617: for (i=0; i<CLSIZE; i++) { ! 618: *(int *)(Prbufmap + i) = PG_V | PG_KW | (pte->pg_pfnum + i); ! 619: mtpr(TBIS, &priobuf[i*NBPG]); ! 620: } ! 621: return pte; ! 622: } ! 623: ! 624: /* Release a cluster, updating its pte's. */ ! 625: ! 626: prclunmap(pte, flag) ! 627: register struct pte *pte; ! 628: { ! 629: register i; ! 630: if ((flag & B_PHYS) == 0) ! 631: munlock(pte->pg_pfnum); ! 632: if ((flag & B_READ) == 0) /* Write to device writes memory */ ! 633: for (i=0; i<CLSIZE; i++) ! 634: (pte+i)->pg_m = 1; ! 635: } ! 636: ! 637: /* Prepare the process' text segment for writing, duplicating it if necessary. */ ! 638: ! 639: prxdup(p) ! 640: register struct proc *p; ! 641: { ! 642: register struct text *xp, *pxp; ! 643: ! 644: if ((pxp = p->p_textp) == 0) ! 645: return 0; ! 646: if (!(pxp->x_flag&XPAGI) && pxp->x_count == 1) { ! 647: pxp->x_flag |= XTRC|XWRIT; ! 648: return 0; ! 649: } ! 650: if (pxp->x_flag&XTRC) ! 651: panic("prxdup"); ! 652: ! 653: for (xp = text; xp < textNTEXT && xp->x_iptr; xp++) ! 654: /* void */ ; ! 655: if (xp >= textNTEXT) ! 656: return (u.u_error = ENOSPC); ! 657: ! 658: xp->x_flag = XLOCK|XTRC|XLOAD; ! 659: xp->x_size = pxp->x_size; ! 660: if (vsxalloc(xp) == NULL) ! 661: return (u.u_error = ENOSPC); ! 662: ! 663: xp->x_count = 1; ! 664: xp->x_ccount = 0; ! 665: xp->x_rssize = 0; ! 666: (xp->x_iptr = pxp->x_iptr)->i_count++; ! 667: ! 668: xlock(pxp); ! 669: --pxp->x_count; ! 670: pxp->x_flag &= ~XLOCK; ! 671: xccdec(pxp, p); ! 672: ! 673: p->p_textp = xp; ! 674: xlink(p); ! 675: p->p_flag &= ~SPAGI; ! 676: ! 677: prxread(p, prusrutl); ! 678: ! 679: xp->x_flag |= XWRIT; ! 680: xp->x_flag &= ~XLOAD; ! 681: xunlock(xp); ! 682: return u.u_error; ! 683: } ! 684: ! 685: prxread(p, up) ! 686: register struct proc *p; ! 687: struct user *up; ! 688: { ! 689: register struct inode *ip = p->p_textp->x_iptr; ! 690: register count; register struct pte *pte; ! 691: register caddr_t vaddr = 0; int waslocked; ! 692: ! 693: caddr_t ubase = u.u_base; unsigned int ucount = u.u_count; ! 694: off_t uoffset = Ltol(u.u_offset); ! 695: ! 696: plock(ip); ! 697: ip->i_flag |= ITEXT; ! 698: ! 699: count = up->u_exdata.ux_tsize; ! 700: if (up->u_exdata.ux_mag == 0413) /* 0413 on 4k file sys */ ! 701: u.u_offset = ltoL(BSIZE(0)); ! 702: else ! 703: u.u_offset = ltoL(sizeof(u.u_exdata)); ! 704: ! 705: u.u_segflg = SEGSYS; ! 706: u.u_count = 0; ! 707: while (count > 0 && u.u_count == 0) { ! 708: pte = prclmap(p, vaddr, &waslocked); ! 709: u.u_base = (caddr_t)priobuf; ! 710: count -= u.u_count = min(count, CLSIZE*NBPG); ! 711: vaddr += u.u_count; ! 712: readi(ip); ! 713: prclunmap(pte, B_WRITE | waslocked); ! 714: } ! 715: prele(ip); ! 716: ! 717: u.u_base = ubase; u.u_count = ucount; ! 718: u.u_offset = ltoL(uoffset); u.u_segflg = SEGUDATA; ! 719: ! 720: return (count ? (u.u_error = EIO) : 0); ! 721: } ! 722: ! 723: struct proc * ! 724: pritop(ip) ! 725: struct inode *ip; ! 726: { ! 727: register struct proc *p; ! 728: ! 729: if ((p = ip->i_un.i_proc) == NULL ! 730: || p->p_pid != ip->i_number - PRMAGIC ! 731: || p->p_stat == 0 || p->p_stat == SZOMB) { ! 732: u.u_error = ENOENT; /* should really be ENXIO */ ! 733: return (NULL); ! 734: } ! 735: return (p); ! 736: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.