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 = &regloc[0]; cp < &regloc[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: }

Defined functions

exec defined in line 29; never used
exece defined in line 35; used 3 times
exit defined in line 600; used 1 times
fork defined in line 837; used 2 times
fork1 defined in line 837; used 2 times
getxfile defined in line 264; used 2 times
rexit defined in line 583; used 2 times
sbreak defined in line 927; used 2 times
setregs defined in line 505; used 1 times
vfork defined in line 832; never used
wait defined in line 739; used 2 times

Defined struct's

a defined in line 929; used 4 times
execa defined in line 23; used 6 times

Defined macros

SCRMAG defined in line 45; used 1 times
  • in line 87
Last modified: 1983-09-05
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 2198
Valid CSS Valid XHTML 1.0 Strict