1: /* 2: * SCCS id @(#)sys1.c 2.1 (Berkeley) 9/4/83 3: */ 4: 5: #include "param.h" 6: #include <sys/systm.h> 7: #include <sys/map.h> 8: #include <sys/dir.h> 9: #include <sys/user.h> 10: #include <sys/proc.h> 11: #include <sys/buf.h> 12: #include <sys/reg.h> 13: #include <sys/inode.h> 14: #include <sys/seg.h> 15: #include <sys/acct.h> 16: #include <sys/file.h> 17: #include <wait.h> 18: 19: 20: /* 21: * exec system call, with and without environments. 22: */ 23: struct execa { 24: char *fname; 25: char **argp; 26: char **envp; 27: }; 28: 29: exec() 30: { 31: ((struct execa *)u.u_ap)->envp = NULL; 32: exece(); 33: } 34: 35: exece() 36: { 37: register nc; 38: register char *cp; 39: register struct buf *bp; 40: register struct execa *uap; 41: memaddr bno; 42: int na, ne, ucp, ap, c; 43: struct inode *ip; 44: #ifdef UCB_SCRIPT 45: #define SCRMAG '#!' 46: extern int schar(); 47: int uid, gid, indir; 48: #endif 49: 50: #ifndef UCB_SYMLINKS 51: if ((ip = namei(uchar, LOOKUP)) == NULL) 52: #else 53: if ((ip = namei(uchar, LOOKUP, 1)) == NULL) 54: #endif 55: return; 56: bno = 0; 57: bp = (struct buf *) NULL; 58: #ifdef UCB_SCRIPT 59: indir = 0; 60: uid = u.u_uid; 61: gid = u.u_gid; 62: if (ip->i_mode&ISUID) 63: uid = ip->i_uid; 64: if (ip->i_mode&ISGID) 65: gid = ip->i_gid; 66: again: 67: #endif 68: if (access(ip, IEXEC)) 69: goto bad; 70: if ((ip->i_mode & IFMT) != IFREG || 71: (ip->i_mode & (IEXEC | (IEXEC >> 3) | (IEXEC >> 6))) == 0) { 72: u.u_error = EACCES; 73: goto bad; 74: } 75: #ifdef UCB_SCRIPT 76: /* moved from getxfile() */ 77: u.u_base = (caddr_t) &u.u_exdata; 78: u.u_count = sizeof u.u_exdata; 79: u.u_offset = 0; 80: u.u_segflg = 1; 81: readi(ip); 82: u.u_segflg = 0; 83: if (u.u_error) 84: goto bad; 85: /* check if script. one level only */ 86: if (indir == 0 87: && u.u_exdata.ux_mag == SCRMAG 88: && u.u_count < sizeof u.u_exdata - sizeof u.u_exdata.ux_mag) 89: { 90: indir++; 91: cp = (char *) &u.u_exdata + sizeof u.u_exdata.ux_mag; 92: while (*cp == ' ' && cp < (char *)&u.u_exdata + sizeof u.u_exdata-1) 93: cp++; 94: u.u_dirp = cp; 95: while (cp < (char *) &u.u_exdata + sizeof u.u_exdata - 1 96: && *cp != '\n') 97: cp++; 98: *cp = '\0'; 99: iput(ip); 100: #ifndef UCB_SYMLINKS 101: if ((ip = namei(schar, LOOKUP)) == NULL) 102: #else 103: if ((ip = namei(schar, LOOKUP, 1)) == NULL) 104: #endif 105: return; 106: goto again; 107: } 108: /*other magic numbers are described in getxfile()*/ 109: #endif 110: 111: /* 112: * Collect arguments on "file" in swap space. 113: */ 114: na = 0; 115: ne = 0; 116: nc = 0; 117: uap = (struct execa *)u.u_ap; 118: #ifndef UCB_NKB 119: if ((bno = malloc(swapmap, (NCARGS + BSIZE - 1) / BSIZE)) == 0) 120: panic("Out of swap"); 121: #else UCB_NKB 122: if ((bno = malloc(swapmap, ctod((int) btoc(NCARGS + BSIZE)))) == 0) 123: panic("Out of swap"); 124: #endif UCB_NKB 125: if (uap->argp) for (;;) { 126: ap = NULL; 127: #ifdef UCB_SCRIPT 128: /* insert script path name as first arg */ 129: if (indir && na == 1) 130: ap = uap->fname; 131: else 132: #endif 133: if (uap->argp) { 134: ap = fuword((caddr_t)uap->argp); 135: uap->argp++; 136: } 137: if (ap==NULL && uap->envp) { 138: uap->argp = NULL; 139: if ((ap = fuword((caddr_t)uap->envp)) == NULL) 140: break; 141: uap->envp++; 142: ne++; 143: } 144: if (ap==NULL) 145: break; 146: na++; 147: if (ap == -1) 148: u.u_error = EFAULT; 149: do { 150: if (nc >= NCARGS - 1) 151: u.u_error = E2BIG; 152: if ((c = fubyte((caddr_t) ap++)) < 0) 153: u.u_error = EFAULT; 154: if (u.u_error) 155: goto bad; 156: if ((nc & BMASK) == 0) { 157: if (bp) { 158: mapout(bp); 159: bdwrite(bp); 160: } 161: #ifndef UCB_NKB 162: bp = getblk(swapdev, swplo + bno + (nc >> BSHIFT)); 163: #else 164: bp = getblk(swapdev, 165: dbtofsb(clrnd(swplo + bno)) + (nc >> BSHIFT)); 166: #endif 167: cp = mapin(bp); 168: } 169: nc++; 170: *cp++ = c; 171: } while (c > 0); 172: } 173: if (bp) { 174: mapout(bp); 175: bdwrite(bp); 176: } 177: bp = 0; 178: nc = (nc + NBPW - 1) & ~(NBPW - 1); 179: #ifndef UCB_SCRIPT 180: if (getxfile(ip, (na * NBPW) + nc) || u.u_error) 181: goto bad; 182: #else 183: if (getxfile(ip, (na * NBPW) + nc, uid, gid) || u.u_error) 184: goto bad; 185: #endif 186: 187: /* 188: * copy back arglist 189: */ 190: 191: ucp = -nc - NBPW; 192: ap = ucp - na * NBPW - 3 * NBPW; 193: u.u_ar0[R6] = ap; 194: suword((caddr_t)ap, na - ne); 195: nc = 0; 196: for (;;) { 197: ap += NBPW; 198: if (na == ne) { 199: suword((caddr_t)ap, 0); 200: ap += NBPW; 201: } 202: if (--na < 0) 203: break; 204: suword((caddr_t)ap, ucp); 205: do { 206: if ((nc & BMASK) == 0) { 207: if (bp) { 208: mapout(bp); 209: bp->b_flags |= B_AGE; 210: brelse(bp); 211: } 212: #ifndef UCB_NKB 213: bp = bread(swapdev, swplo + bno + (nc>>BSHIFT)); 214: #else 215: bp = bread(swapdev, 216: dbtofsb(clrnd(swplo + bno)) + (nc >> BSHIFT)); 217: #endif 218: bp->b_flags &= ~B_DELWRI; 219: cp = mapin(bp); 220: #ifdef UCB_SCRIPT 221: /* stick in interpreter name for accounting */ 222: if (indir && nc == 0) 223: bcopy(cp, (caddr_t)u.u_dbuf, DIRSIZ); 224: #endif 225: } 226: subyte((caddr_t)ucp++, (c = *cp++)); 227: nc++; 228: } while(c & 0377); 229: } 230: suword((caddr_t) ap, 0); 231: suword((caddr_t) (-NBPW), 0); 232: if (bp) { 233: mapout(bp); 234: bp->b_flags |= B_AGE; 235: brelse(bp); 236: bp = 0; 237: } 238: setregs(); 239: 240: bad: 241: if (bp) { 242: mapout(bp); 243: bp->b_flags |= B_AGE; 244: brelse(bp); 245: } 246: if (bno) 247: #ifndef UCB_NKB 248: mfree(swapmap, (NCARGS + BSIZE - 1) / BSIZE, bno); 249: #else 250: mfree(swapmap, ctod((int) btoc(NCARGS + BSIZE)), bno); 251: #endif 252: iput(ip); 253: } 254: 255: /* 256: * Read in and set up memory for executed file. 257: * Zero return is normal; 258: * non-zero means only the text is being replaced 259: */ 260: #ifdef UCB_SCRIPT 261: getxfile(ip, nargc, uid, gid) 262: int nargc, uid, gid; 263: #else 264: getxfile(ip, nargc) 265: #endif 266: register struct inode *ip; 267: { 268: register unsigned ds; 269: register sep; 270: register unsigned ts, ss; 271: register i, overlay; 272: #ifdef MENLO_OVLY 273: register ovflag,ovmax; 274: struct u_ovd sovdata; 275: unsigned ovhead[1 + NOVL]; 276: #endif 277: long lsize; 278: 279: #ifndef UCB_SCRIPT 280: /* 281: * read in first few bytes 282: * of file for segment 283: * sizes: 284: * ux_mag = A_MAGIC1/A_MAGIC2/A_MAGIC3/A_MAGIC4 285: * A_MAGIC1 is plain executable 286: * A_MAGIC2 is RO text 287: * A_MAGIC3 is separated ID 288: * A_MAGIC4 is overlaid text 289: */ 290: #ifdef MENLO_OVLY 291: /* 292: * ux_mag = A_MAGIC1/A_MAGIC2/A_MAGIC3/A_MAGIC4/A_MAGIC5/A_MAGIC6 293: * A_MAGIC5 is nonseparate auto-overlay 294: * A_MAGIC6 is separate auto overlay 295: */ 296: #endif 297: 298: u.u_base = (caddr_t) &u.u_exdata; 299: u.u_count = sizeof(u.u_exdata); 300: u.u_offset = 0; 301: u.u_segflg = 1; 302: readi(ip); 303: u.u_segflg = 0; 304: if (u.u_error) 305: goto bad; 306: if (u.u_count != 0) { 307: u.u_error = ENOEXEC; 308: goto bad; 309: } 310: #endif 311: sep = 0; 312: overlay = 0; 313: #ifdef MENLO_OVLY 314: ovflag = 0; 315: #endif 316: if (u.u_exdata.ux_mag == A_MAGIC1) { 317: lsize = (long) u.u_exdata.ux_dsize + u.u_exdata.ux_tsize; 318: u.u_exdata.ux_dsize = lsize; 319: if (lsize != u.u_exdata.ux_dsize) { /* check overflow */ 320: u.u_error = ENOMEM; 321: goto bad; 322: } 323: u.u_exdata.ux_tsize = 0; 324: } else if (u.u_exdata.ux_mag == A_MAGIC3) 325: sep++; 326: else if (u.u_exdata.ux_mag == A_MAGIC4) 327: overlay++; 328: #ifdef MENLO_OVLY 329: else if (u.u_exdata.ux_mag == A_MAGIC5) 330: ovflag++; 331: else if (u.u_exdata.ux_mag == A_MAGIC6) { 332: sep++; 333: ovflag++; 334: } 335: #endif 336: else if (u.u_exdata.ux_mag != A_MAGIC2) { 337: u.u_error = ENOEXEC; 338: goto bad; 339: } 340: if (u.u_exdata.ux_tsize!=0 && (ip->i_flag&ITEXT)==0 && ip->i_count!=1) { 341: u.u_error = ETXTBSY; 342: goto bad; 343: } 344: 345: /* 346: * find text and data sizes 347: * try them out for possible 348: * overflow of max sizes 349: */ 350: ts = btoc(u.u_exdata.ux_tsize); 351: lsize = (long) u.u_exdata.ux_dsize + u.u_exdata.ux_bsize; 352: if (lsize != (unsigned) lsize) { 353: u.u_error = ENOMEM; 354: goto bad; 355: } 356: ds = btoc(lsize); 357: ss = SSIZE + btoc(nargc); 358: #ifdef MENLO_OVLY 359: 360: /* 361: * if auto overlay get second header 362: */ 363: 364: sovdata = u.u_ovdata; 365: u.u_ovdata.uo_ovbase = 0; 366: u.u_ovdata.uo_curov = 0; 367: if (ovflag) { 368: u.u_base = (caddr_t) ovhead; 369: u.u_count = sizeof(ovhead); 370: u.u_offset = sizeof(u.u_exdata); 371: u.u_segflg = 1; 372: readi(ip); 373: u.u_segflg = 0; 374: if (u.u_count != 0) 375: u.u_error = ENOEXEC; 376: if (u.u_error) { 377: u.u_ovdata = sovdata; 378: goto bad; 379: } 380: /* set beginning of overlay segment */ 381: u.u_ovdata.uo_ovbase = ctos(ts); 382: 383: /* 0th entry is max size of the overlays */ 384: ovmax = btoc(ovhead[0]); 385: 386: /* set max number of segm. registers to be used */ 387: u.u_ovdata.uo_nseg = ctos(ovmax); 388: 389: /* set base of data space */ 390: u.u_ovdata.uo_dbase = stoc(u.u_ovdata.uo_ovbase + u.u_ovdata.uo_nseg); 391: /* 392: * Set up a table of offsets to each of the 393: * overlay segements. The ith overlay runs 394: * from ov_offst[i-1] to ov_offst[i]. 395: */ 396: u.u_ovdata.uo_ov_offst[0] = ts; 397: for (i = 1; i < 1 + NOVL; i++) { 398: register t; 399: /* check if any overlay is larger than ovmax */ 400: if ((t=btoc(ovhead[i])) > ovmax) { 401: u.u_error = ENOEXEC; 402: u.u_ovdata = sovdata; 403: goto bad; 404: } 405: u.u_ovdata.uo_ov_offst[i] = 406: t + u.u_ovdata.uo_ov_offst[i - 1]; 407: } 408: } 409: 410: #endif 411: if (overlay) { 412: if (u.u_sep == 0 && ctos(ts) != ctos(u.u_tsize) || nargc) { 413: u.u_error = ENOMEM; 414: goto bad; 415: } 416: ds = u.u_dsize; 417: ss = u.u_ssize; 418: sep = u.u_sep; 419: xfree(); 420: xalloc(ip); 421: u.u_ar0[PC] = u.u_exdata.ux_entloc & ~01; 422: } else { 423: if (estabur(ts, ds, ss, sep, RO)) { 424: #ifdef MENLO_OVLY 425: u.u_ovdata = sovdata; 426: #endif 427: goto bad; 428: } 429: 430: /* 431: * allocate and clear core 432: * at this point, committed 433: * to the new image 434: */ 435: 436: u.u_prof.pr_scale = 0; 437: #ifdef VIRUS_VFORK 438: if (u.u_procp->p_flag & SVFORK) 439: endvfork(); 440: else 441: xfree(); 442: expand(ds, S_DATA); 443: clear(u.u_procp->p_daddr, ds); 444: expand(ss,S_STACK); 445: clear(u.u_procp->p_saddr, ss); 446: #else 447: xfree(); 448: i = USIZE + ds + ss; 449: expand(i); 450: clear(u.u_procp->p_addr + USIZE, i - USIZE); 451: #endif 452: xalloc(ip); 453: 454: /* 455: * read in data segment 456: */ 457: estabur((unsigned)0, ds, (unsigned)0, 0, RO); 458: u.u_base = 0; 459: #ifndef MENLO_OVLY 460: u.u_offset = sizeof(u.u_exdata) + u.u_exdata.ux_tsize; 461: #else 462: u.u_offset = sizeof(u.u_exdata); 463: if (ovflag) { 464: u.u_offset += sizeof(ovhead); 465: u.u_offset += (((long)u.u_ovdata.uo_ov_offst[NOVL]) << 6); 466: } 467: else 468: u.u_offset += u.u_exdata.ux_tsize; 469: #endif 470: u.u_count = u.u_exdata.ux_dsize; 471: readi(ip); 472: 473: /* 474: * set SUID/SGID protections, if no tracing 475: */ 476: if ((u.u_procp->p_flag & STRC) == 0) { 477: #ifndef UCB_SCRIPT 478: if (ip->i_mode & ISUID) 479: if (u.u_uid != 0) { 480: u.u_uid = ip->i_uid; 481: u.u_procp->p_uid = ip->i_uid; 482: } 483: if (ip->i_mode&ISGID) 484: u.u_gid = ip->i_gid; 485: #else 486: u.u_uid = uid; 487: u.u_procp->p_uid = uid; 488: u.u_gid = gid; 489: #endif 490: } else 491: psignal(u.u_procp, SIGTRAP); 492: } 493: u.u_tsize = ts; 494: u.u_dsize = ds; 495: u.u_ssize = ss; 496: u.u_sep = sep; 497: estabur(ts, ds, ss, sep, RO); 498: bad: 499: return(overlay); 500: } 501: 502: /* 503: * Clear registers on exec 504: */ 505: setregs() 506: { 507: #ifdef MENLO_JCL 508: register int (**rp)(); 509: long sigmask; 510: #else 511: register int *rp; 512: #endif 513: register char *cp; 514: register i; 515: 516: #ifndef MENLO_JCL 517: for(rp = &u.u_signal[0]; rp < &u.u_signal[NSIG]; rp++) 518: if ((*rp & 1) == 0) 519: *rp = 0; 520: #else 521: u.u_procp->p_flag &= ~SNUSIG; 522: for(rp = &u.u_signal[1], sigmask = 1L; rp < &u.u_signal[NSIG]; 523: sigmask <<= 1, rp++) { 524: switch (*rp) { 525: 526: case SIG_HOLD: 527: u.u_procp->p_flag |= SNUSIG; 528: continue; 529: case SIG_IGN: 530: case SIG_DFL: 531: continue; 532: 533: default: 534: /* 535: * Normal or deferring catch; revert to default. 536: */ 537: (void) _spl6(); 538: *rp = SIG_DFL; 539: if ((int)SIG_DFL & 1) 540: u.u_procp->p_siga0 |= sigmask; 541: else 542: u.u_procp->p_siga0 &= ~sigmask; 543: if ((int)SIG_DFL & 2) 544: u.u_procp->p_siga1 |= sigmask; 545: else 546: u.u_procp->p_siga1 &= ~sigmask; 547: (void) _spl0(); 548: continue; 549: } 550: } 551: #endif 552: for(cp = ®loc[0]; cp < ®loc[6];) 553: u.u_ar0[*cp++] = 0; 554: u.u_ar0[PC] = u.u_exdata.ux_entloc & ~01; 555: #ifndef NONFP 556: for(rp = (int *)&u.u_fps; rp < (int *)&u.u_fps.u_fpregs[6];) 557: *rp++ = 0; 558: #endif 559: for(i=0; i<NOFILE; i++) { 560: if (u.u_pofile[i]&EXCLOSE) { 561: #ifndef UCB_NET 562: closef(u.u_ofile[i]); 563: #else 564: closef(u.u_ofile[i],1); 565: #endif 566: u.u_ofile[i] = NULL; 567: u.u_pofile[i] &= ~EXCLOSE; 568: } 569: } 570: #ifdef ACCT 571: u.u_acflag &= ~AFORK; 572: #endif 573: /* 574: * Remember file name. 575: */ 576: bcopy((caddr_t)u.u_dbuf, (caddr_t)u.u_comm, DIRSIZ); 577: } 578: 579: /* 580: * exit system call: 581: * pass back caller's arg 582: */ 583: rexit() 584: { 585: register struct a { 586: int rval; 587: } *uap; 588: 589: uap = (struct a *)u.u_ap; 590: exit((uap->rval & 0377) << 8); 591: } 592: 593: /* 594: * Release resources. 595: * Save u. area for parent to look at. 596: * Enter zombie state. 597: * Wake up parent and init processes, 598: * and dispose of children. 599: */ 600: exit(rv) 601: { 602: register int i; 603: register struct proc *p, *q; 604: register struct file *f; 605: 606: p = u.u_procp; 607: p->p_flag &= ~(STRC|SULOCK); 608: p->p_clktim = 0; 609: #ifdef CGL_RTP 610: /* 611: * if this a "real time" process that is dying 612: * remove the rtpp flag. 613: */ 614: if (rtpp != NULL && rtpp == p) 615: rtpp = NULL; 616: #endif 617: #ifdef MENLO_JCL 618: (void) _spl6(); 619: if ((int)SIG_IGN & 1) 620: p->p_siga0 = ~0L; 621: else 622: p->p_siga0 = 0L; 623: if ((int)SIG_IGN & 2) 624: p->p_siga1 = ~0L; 625: else 626: p->p_siga1 = 0L; 627: (void) _spl0(); 628: #endif 629: for(i=0; i<NSIG; i++) 630: u.u_signal[i] = SIG_IGN; 631: for(i=0; i<NOFILE; i++) { 632: f = u.u_ofile[i]; 633: u.u_ofile[i] = NULL; 634: #ifndef UCB_NET 635: closef(f); 636: #else 637: closef(f,1); 638: #endif 639: } 640: plock(u.u_cdir); 641: iput(u.u_cdir); 642: if (u.u_rdir) { 643: plock(u.u_rdir); 644: iput(u.u_rdir); 645: } 646: #ifdef ACCT 647: acct(); 648: #endif ACCT 649: #ifdef VIRUS_VFORK 650: if (p->p_flag & SVFORK) { 651: endvfork(); 652: } else { 653: xfree(); 654: mfree(coremap, p->p_dsize, p->p_daddr); 655: mfree(coremap, p->p_ssize, p->p_saddr); 656: } 657: mfree(coremap, USIZE, p->p_addr); 658: #else VIRUS_VFORK 659: xfree(); 660: mfree(coremap, p->p_size, p->p_addr); 661: #endif VIRUS_VFORK 662: p->p_stat = SZOMB; 663: if (p->p_pid == 1) { 664: /* 665: * If /etc/init is not found by the icode, 666: * the stack size will still be zero when it exits. 667: * Don't panic: we're unlikely to find init after a reboot, 668: * either. 669: */ 670: if (u.u_ssize == 0) { 671: printf("Can't exec /etc/init\n"); 672: for (;;) 673: idle(); 674: } 675: else 676: panic("init died"); 677: } 678: p->p_un.xp_xstat = rv; 679: p->p_un.xp_utime = u.u_cutime + u.u_utime; 680: p->p_un.xp_stime = u.u_cstime + u.u_stime; 681: #ifdef UCB_LOGIN 682: p->p_un.xp_login = u.u_login; 683: #endif 684: #ifdef MENLO_JCL 685: for(q = &proc[0]; q <= maxproc; q++) 686: if (q->p_pptr == p) { 687: q->p_pptr = &proc[1]; 688: q->p_ppid = 1; 689: wakeup((caddr_t)&proc[1]); 690: /* 691: * Traced processes are killed 692: * since their existence means someone is screwing up. 693: * Stopped processes are sent a hangup and a continue. 694: * This is designed to be ``safe'' for setuid 695: * processes since they must be willing to tolerate 696: * hangups anyways. 697: */ 698: if (q->p_flag&STRC) { 699: q->p_flag &= ~STRC; 700: psignal(q, SIGKILL); 701: } else if (q->p_stat == SSTOP) { 702: psignal(q, SIGHUP); 703: psignal(q, SIGCONT); 704: } 705: /* 706: * Protect this process from future 707: * tty signals, clear TSTP/TTIN/TTOU if pending, 708: * and set SDETACH bit on procs. 709: */ 710: spgrp(q, -1); 711: } 712: wakeup((caddr_t)p->p_pptr); 713: psignal(p->p_pptr, SIGCHLD); 714: #else 715: for(q = &proc[0]; q <= maxproc; q++) 716: if (q->p_ppid == p->p_pid) { 717: wakeup((caddr_t)&proc[1]); 718: q->p_ppid = 1; 719: if (q->p_stat==SSTOP) 720: setrun(q); 721: } 722: for(q = &proc[0]; q <= maxproc; q++) 723: if (p->p_ppid == q->p_pid) { 724: wakeup((caddr_t)q); 725: swtch(); 726: /* no return */ 727: } 728: #endif 729: swtch(); 730: } 731: 732: /* 733: * Wait system call. 734: * Search for a terminated (zombie) child, 735: * finally lay it to rest, and collect its status. 736: * Look also for stopped (traced) children, 737: * and pass back status from them. 738: */ 739: wait() 740: { 741: register f; 742: register struct proc *p; 743: #ifdef MENLO_JCL 744: register options; 745: 746: options = (u.u_ar0[RPS] & PS_ALLCC) == PS_ALLCC ? u.u_ar0[R0] : 0; 747: #endif 748: f = 0; 749: 750: loop: 751: for(p = &proc[0]; p <= maxproc; p++) 752: #ifdef MENLO_JCL 753: if (p->p_pptr == u.u_procp) 754: #else 755: if (p->p_ppid == u.u_procp->p_pid) 756: #endif 757: { 758: f++; 759: if (p->p_stat == SZOMB) { 760: u.u_r.r_val1 = p->p_pid; 761: u.u_r.r_val2 = p->p_un.xp_xstat; 762: #ifdef MENLO_JCL 763: p->p_un.xp_xstat = 0; 764: p->p_pptr = 0; 765: p->p_siga0 = 0L; 766: p->p_siga1 = 0L; 767: p->p_cursig = 0; 768: #endif 769: u.u_cutime += p->p_un.xp_utime; 770: u.u_cstime += p->p_un.xp_stime; 771: p->p_pid = 0; 772: p->p_ppid = 0; 773: p->p_pgrp = 0; 774: p->p_sig = 0; 775: p->p_flag = 0; 776: p->p_wchan = 0; 777: p->p_stat = NULL; 778: if (p == maxproc) 779: while (maxproc->p_stat == NULL) 780: maxproc--; 781: return; 782: } 783: if (p->p_stat == SSTOP && (p->p_flag & SWTED) == 0 && 784: (p->p_flag & STRC 785: #ifdef MENLO_JCL 786: || options & WUNTRACED 787: #endif 788: )){ 789: p->p_flag |= SWTED; 790: u.u_r.r_val1 = p->p_pid; 791: #ifdef MENLO_JCL 792: u.u_r.r_val2 = (p->p_cursig << 8) | 0177; 793: #else 794: u.u_r.r_val2 = (fsig(p) << 8) | 0177; 795: #endif 796: return; 797: } 798: } 799: if (f) { 800: #ifdef MENLO_JCL 801: if (options & WNOHANG) { 802: u.u_r.r_val1 = 0; 803: return; 804: } else { 805: if ((u.u_procp->p_flag & SNUSIG) && save(u.u_qsav)) { 806: u.u_eosys = RESTARTSYS; 807: return; 808: } 809: sleep((caddr_t)u.u_procp, PWAIT); 810: goto loop; 811: } 812: #else 813: sleep((caddr_t) u.u_procp, PWAIT); 814: goto loop; 815: #endif 816: } 817: u.u_error = ECHILD; 818: } 819: 820: /* 821: * fork system call. 822: */ 823: #ifdef VIRUS_VFORK 824: fork() 825: { 826: fork1(0); 827: } 828: 829: /* 830: * vfork system call 831: */ 832: vfork() 833: { 834: fork1(1); 835: } 836: 837: fork1(isvfork) 838: #else VIRUS_VFORK 839: fork() 840: #endif 841: { 842: #ifdef UCB_PGRP 843: register struct proc *p1; 844: struct proc *p2; 845: register a, pg; 846: #else 847: register struct proc *p1, *p2; 848: register a; 849: #endif 850: 851: /* 852: * Make sure there's enough swap space for max 853: * core image, thus reducing chances of running out 854: */ 855: if ((a = malloc(swapmap, ctod(maxmem))) == 0) { 856: u.u_error = ENOMEM; 857: goto out; 858: } 859: mfree(swapmap, ctod(maxmem), a); 860: a = 0; 861: #ifdef UCB_PGRP 862: pg = u.u_procp->p_pgrp; /* process group number */ 863: #endif 864: p2 = NULL; 865: for(p1 = proc; p1 < procNPROC; p1++) { 866: if (p1->p_stat==NULL && p2==NULL) 867: p2 = p1; 868: else { 869: /* 870: * Exempt low positive uids (0-15) for users like uucp 871: * and network, which shouldn't lose limits. 872: */ 873: #ifdef UCB_PGRP 874: if (p1->p_pgrp==pg && (unsigned) u.u_uid>=16 875: && p1->p_stat!=NULL) 876: a++; 877: #else 878: if ((p1->p_uid==u.u_uid && p1->p_stat!=NULL) 879: && ((unsigned) u.u_uid >= 16)) 880: a++; 881: #endif 882: } 883: } 884: /* 885: * Disallow if 886: * No processes at all; 887: * not su and too many procs owned (or in pgrp, if UCB_PGRP set); 888: * or not su and would take last slot. 889: */ 890: if (p2 == NULL) 891: tablefull("proc"); 892: if (p2 == NULL || (u.u_uid != 0 && (p2 == procNPROC-1 || a > MAXUPRC))){ 893: u.u_error = EAGAIN; 894: goto out; 895: } 896: p1 = u.u_procp; 897: #ifdef VIRUS_VFORK 898: if (newproc(isvfork)) 899: #else 900: if (newproc()) 901: #endif 902: { 903: u.u_r.r_val1 = p1->p_pid; 904: u.u_start = time; 905: u.u_cstime = 0; 906: u.u_stime = 0; 907: u.u_cutime = 0; 908: u.u_utime = 0; 909: #ifdef UCB_LOGIN 910: u.u_login = 0; 911: #endif 912: #ifdef ACCT 913: u.u_acflag = AFORK; 914: #endif 915: return; 916: } 917: u.u_r.r_val1 = p2->p_pid; 918: 919: out: 920: u.u_ar0[R7] += NBPW; 921: } 922: 923: /* 924: * break system call. 925: * -- bad planning: "break" is a dirty word in C. 926: */ 927: sbreak() 928: { 929: struct a { 930: char *nsiz; 931: }; 932: register a, n, d; 933: int i; 934: 935: /* 936: * set n to new data size 937: * set d to new-old 938: * set n to new total size 939: */ 940: 941: n = btoc((int) ((struct a *) u.u_ap)->nsiz); 942: if (!u.u_sep) 943: #ifdef MENLO_OVLY 944: if (u.u_ovdata.uo_ovbase) 945: n -= u.u_ovdata.uo_dbase; 946: else 947: n -= ctos(u.u_tsize) * stoc(1); 948: #else 949: n -= ctos(u.u_tsize) * stoc(1); 950: #endif 951: if (n < 0) 952: n = 0; 953: #ifdef VIRUS_VFORK 954: d = n - u.u_dsize; 955: if (estabur(u.u_tsize, n, u.u_ssize, u.u_sep, RO)) 956: return; 957: expand(n,S_DATA); 958: if (d > 0) 959: clear(u.u_procp->p_daddr + u.u_dsize, d); 960: u.u_dsize = n; 961: 962: #else VIRUS_VFORK 963: d = n - u.u_dsize; 964: n += USIZE+u.u_ssize; 965: if (estabur(u.u_tsize, u.u_dsize+d, u.u_ssize, u.u_sep, RO)) 966: return; 967: u.u_dsize += d; 968: if (d > 0) 969: goto bigger; 970: a = u.u_procp->p_addr + n - u.u_ssize; 971: copy(a-d, a, u.u_ssize); /* d is negative */ 972: expand(n); 973: return; 974: 975: bigger: 976: expand(n); 977: a = u.u_procp->p_addr + n - u.u_ssize - d; 978: n = u.u_ssize; 979: while (n >= d) { 980: n -= d; 981: copy(a+n, a+n+d, d); 982: } 983: copy(a, a+d, n); 984: clear(a, d); 985: #endif VIRUS_VFORK 986: }