1 /* kern_proc.c 4.63 83/05/21 */ 2 3 #include "../machine/reg.h" 4 #include "../machine/pte.h" 5 #include "../machine/psl.h" 6 7 #include "../h/param.h" 8 #include "../h/systm.h" 9 #include "../h/map.h" 10 #include "../h/dir.h" 11 #include "../h/user.h" 12 #include "../h/kernel.h" 13 #include "../h/proc.h" 14 #include "../h/buf.h" 15 #include "../h/inode.h" 16 #include "../h/seg.h" 17 #include "../h/acct.h" 18 #include "../h/wait.h" 19 #include "../h/vm.h" 20 #include "../h/text.h" 21 #include "../h/file.h" 22 #include "../h/quota.h" 23 #include "../h/descrip.h" 24 #include "../h/uio.h" 25 #include "../h/mbuf.h" 26 #include "../h/nami.h" 27 28 gethostid() 29 { 30 31 u.u_r.r_val1 = hostid; 32 } 33 34 sethostid() 35 { 36 struct a { 37 int hostid; 38 } *uap = (struct a *)u.u_ap; 39 40 if (suser()) 41 hostid = uap->hostid; 42 } 43 44 gethostname() 45 { 46 register struct a { 47 char *hostname; 48 int len; 49 } *uap = (struct a *)u.u_ap; 50 register u_int len; 51 52 len = uap->len; 53 if (len > hostnamelen + 1) 54 len = hostnamelen + 1; 55 u.u_error = copyout((caddr_t)hostname, (caddr_t)uap->hostname, len); 56 } 57 58 sethostname() 59 { 60 register struct a { 61 char *hostname; 62 u_int len; 63 } *uap = (struct a *)u.u_ap; 64 65 if (!suser()) 66 return; 67 if (uap->len > sizeof (hostname) - 1) { 68 u.u_error = EINVAL; 69 return; 70 } 71 hostnamelen = uap->len; 72 u.u_error = copyin((caddr_t)uap->hostname, hostname, uap->len); 73 hostname[hostnamelen] = 0; 74 } 75 76 /* 77 * exec system call, with and without environments. 78 */ 79 struct execa { 80 char *fname; 81 char **argp; 82 char **envp; 83 }; 84 85 execv() 86 { 87 ((struct execa *)u.u_ap)->envp = NULL; 88 execve(); 89 } 90 91 execve() 92 { 93 register nc; 94 register char *cp; 95 register struct buf *bp; 96 register struct execa *uap; 97 int na, ne, ucp, ap, c; 98 int indir, uid, gid; 99 char *sharg; 100 struct inode *ip; 101 swblk_t bno; 102 char cfname[MAXCOMLEN + 1]; 103 char cfarg[SHSIZE]; 104 int resid; 105 106 if ((ip = namei(uchar, LOOKUP, 1)) == NULL) 107 return; 108 bno = 0; 109 bp = 0; 110 indir = 0; 111 uid = u.u_uid; 112 gid = u.u_gid; 113 if (ip->i_mode & ISUID) 114 uid = ip->i_uid; 115 if (ip->i_mode & ISGID) 116 gid = ip->i_gid; 117 118 again: 119 if (access(ip, IEXEC)) 120 goto bad; 121 if ((u.u_procp->p_flag&STRC) && access(ip, IREAD)) 122 goto bad; 123 if ((ip->i_mode & IFMT) != IFREG || 124 (ip->i_mode & (IEXEC|(IEXEC>>3)|(IEXEC>>6))) == 0) { 125 u.u_error = EACCES; 126 goto bad; 127 } 128 129 /* 130 * Read in first few bytes of file for segment sizes, ux_mag: 131 * 407 = plain executable 132 * 410 = RO text 133 * 413 = demand paged RO text 134 * Also an ASCII line beginning with #! is 135 * the file name of a ``shell'' and arguments may be prepended 136 * to the argument list if given here. 137 * 138 * SHELL NAMES ARE LIMITED IN LENGTH. 139 * 140 * ONLY ONE ARGUMENT MAY BE PASSED TO THE SHELL FROM 141 * THE ASCII LINE. 142 */ 143 u.u_exdata.ux_shell[0] = 0; /* for zero length files */ 144 u.u_error = rdwri(UIO_READ, ip, (caddr_t)&u.u_exdata, sizeof (u.u_exdata), 145 0, 1, &resid); 146 if (u.u_error) 147 goto bad; 148 u.u_count = resid; 149 #ifndef lint 150 if (u.u_count > sizeof(u.u_exdata) - sizeof(u.u_exdata.Ux_A) && 151 u.u_exdata.ux_shell[0] != '#') { 152 u.u_error = ENOEXEC; 153 goto bad; 154 } 155 #endif 156 switch (u.u_exdata.ux_mag) { 157 158 case 0407: 159 u.u_exdata.ux_dsize += u.u_exdata.ux_tsize; 160 u.u_exdata.ux_tsize = 0; 161 break; 162 163 case 0413: 164 case 0410: 165 if (u.u_exdata.ux_tsize == 0) { 166 u.u_error = ENOEXEC; 167 goto bad; 168 } 169 break; 170 171 default: 172 if (u.u_exdata.ux_shell[0] != '#' || 173 u.u_exdata.ux_shell[1] != '!' || 174 indir) { 175 u.u_error = ENOEXEC; 176 goto bad; 177 } 178 cp = &u.u_exdata.ux_shell[2]; /* skip "#!" */ 179 while (cp < &u.u_exdata.ux_shell[SHSIZE]) { 180 if (*cp == '\t') 181 *cp = ' '; 182 else if (*cp == '\n') { 183 *cp = '\0'; 184 break; 185 } 186 cp++; 187 } 188 if (*cp != '\0') { 189 u.u_error = ENOEXEC; 190 goto bad; 191 } 192 cp = &u.u_exdata.ux_shell[2]; 193 while (*cp == ' ') 194 cp++; 195 u.u_dirp = cp; 196 while (*cp && *cp != ' ') 197 cp++; 198 sharg = NULL; 199 if (*cp) { 200 *cp++ = '\0'; 201 while (*cp == ' ') 202 cp++; 203 if (*cp) { 204 bcopy((caddr_t)cp, (caddr_t)cfarg, SHSIZE); 205 sharg = cfarg; 206 } 207 } 208 if (u.u_dent.d_namlen > MAXCOMLEN) 209 u.u_dent.d_namlen = MAXCOMLEN; 210 bcopy((caddr_t)u.u_dent.d_name, (caddr_t)cfname, 211 (unsigned)(u.u_dent.d_namlen + 1)); 212 cfname[MAXCOMLEN] = 0; 213 indir = 1; 214 iput(ip); 215 ip = namei(schar, LOOKUP, 1); 216 if (ip == NULL) 217 return; 218 goto again; 219 } 220 221 /* 222 * Collect arguments on "file" in swap space. 223 */ 224 na = 0; 225 ne = 0; 226 nc = 0; 227 uap = (struct execa *)u.u_ap; 228 if ((bno = rmalloc(argmap, (long)ctod(clrnd((int)btoc(NCARGS))))) == 0) { 229 swkill(u.u_procp, "exece"); 230 goto bad; 231 } 232 if (bno % CLSIZE) 233 panic("execa rmalloc"); 234 if (uap->argp) for (;;) { 235 ap = NULL; 236 if (indir && (na == 1 || na == 2 && sharg)) 237 ap = (int)uap->fname; 238 else if (uap->argp) { 239 ap = fuword((caddr_t)uap->argp); 240 uap->argp++; 241 } 242 if (ap==NULL && uap->envp) { 243 uap->argp = NULL; 244 if ((ap = fuword((caddr_t)uap->envp)) == NULL) 245 break; 246 uap->envp++; 247 ne++; 248 } 249 if (ap == NULL) 250 break; 251 na++; 252 if (ap == -1) 253 u.u_error = EFAULT; 254 do { 255 if (nc >= NCARGS-1) 256 u.u_error = E2BIG; 257 if (indir && na == 2 && sharg != NULL) 258 c = *sharg++ & 0377; 259 else if ((c = fubyte((caddr_t)ap++)) < 0) 260 u.u_error = EFAULT; 261 if (u.u_error) { 262 if (bp) 263 brelse(bp); 264 bp = 0; 265 goto badarg; 266 } 267 if (nc % (CLSIZE*NBPG) == 0) { 268 if (bp) 269 bdwrite(bp); 270 bp = getblk(argdev, bno + ctod(nc / NBPG), 271 CLSIZE*NBPG); 272 cp = bp->b_un.b_addr; 273 } 274 nc++; 275 *cp++ = c; 276 } while (c > 0); 277 } 278 if (bp) 279 bdwrite(bp); 280 bp = 0; 281 nc = (nc + NBPW-1) & ~(NBPW-1); 282 if (indir) { 283 u.u_dent.d_namlen = strlen(cfname); 284 bcopy((caddr_t)cfname, (caddr_t)u.u_dent.d_name, 285 (unsigned)(u.u_dent.d_namlen + 1)); 286 } 287 getxfile(ip, nc + (na+4)*NBPW, uid, gid); 288 if (u.u_error) { 289 badarg: 290 for (c = 0; c < nc; c += CLSIZE*NBPG) { 291 bp = baddr(argdev, bno + ctod(c / NBPG), CLSIZE*NBPG); 292 if (bp) { 293 bp->b_flags |= B_AGE; /* throw away */ 294 bp->b_flags &= ~B_DELWRI; /* cancel io */ 295 brelse(bp); 296 bp = 0; 297 } 298 } 299 goto bad; 300 } 301 302 /* 303 * copy back arglist 304 */ 305 ucp = USRSTACK - nc - NBPW; 306 ap = ucp - na*NBPW - 3*NBPW; 307 u.u_ar0[SP] = ap; 308 (void) suword((caddr_t)ap, na-ne); 309 nc = 0; 310 for (;;) { 311 ap += NBPW; 312 if (na==ne) { 313 (void) suword((caddr_t)ap, 0); 314 ap += NBPW; 315 } 316 if (--na < 0) 317 break; 318 (void) suword((caddr_t)ap, ucp); 319 do { 320 if (nc % (CLSIZE*NBPG) == 0) { 321 if (bp) 322 brelse(bp); 323 bp = bread(argdev, bno + ctod(nc / NBPG), 324 CLSIZE*NBPG); 325 bp->b_flags |= B_AGE; /* throw away */ 326 bp->b_flags &= ~B_DELWRI; /* cancel io */ 327 cp = bp->b_un.b_addr; 328 } 329 (void) subyte((caddr_t)ucp++, (c = *cp++)); 330 nc++; 331 } while(c&0377); 332 } 333 (void) suword((caddr_t)ap, 0); 334 setregs(); 335 bad: 336 if (bp) 337 brelse(bp); 338 if (bno) 339 rmfree(argmap, (long)ctod(clrnd((int) btoc(NCARGS))), bno); 340 iput(ip); 341 } 342 343 /* 344 * Read in and set up memory for executed file. 345 */ 346 getxfile(ip, nargc, uid, gid) 347 register struct inode *ip; 348 { 349 register size_t ts, ds, ss; 350 int pagi; 351 352 if (u.u_exdata.ux_mag == 0413) 353 pagi = SPAGI; 354 else 355 pagi = 0; 356 if (u.u_exdata.ux_tsize!=0 && (ip->i_flag&ITEXT)==0 && 357 ip->i_count!=1) { 358 register struct file *fp; 359 360 for (fp = file; fp < fileNFILE; fp++) { 361 if (fp->f_type == DTYPE_FILE && 362 fp->f_count > 0 && 363 fp->f_inode == ip && (fp->f_flag&FWRITE)) { 364 u.u_error = ETXTBSY; 365 goto bad; 366 } 367 } 368 } 369 370 /* 371 * Compute text and data sizes and make sure not too large. 372 */ 373 ts = clrnd(btoc(u.u_exdata.ux_tsize)); 374 ds = clrnd(btoc((u.u_exdata.ux_dsize+u.u_exdata.ux_bsize))); 375 ss = clrnd(SSIZE + btoc(nargc)); 376 if (chksize(ts, ds, ss)) 377 goto bad; 378 379 /* 380 * Make sure enough space to start process. 381 */ 382 u.u_cdmap = zdmap; 383 u.u_csmap = zdmap; 384 if (swpexpand(ds, ss, &u.u_cdmap, &u.u_csmap) == NULL) 385 goto bad; 386 387 /* 388 * At this point, committed to the new image! 389 * Release virtual memory resources of old process, and 390 * initialize the virtual memory of the new process. 391 * If we resulted from vfork(), instead wakeup our 392 * parent who will set SVFDONE when he has taken back 393 * our resources. 394 */ 395 if ((u.u_procp->p_flag & SVFORK) == 0) 396 vrelvm(); 397 else { 398 u.u_procp->p_flag &= ~SVFORK; 399 u.u_procp->p_flag |= SKEEP; 400 wakeup((caddr_t)u.u_procp); 401 while ((u.u_procp->p_flag & SVFDONE) == 0) 402 sleep((caddr_t)u.u_procp, PZERO - 1); 403 u.u_procp->p_flag &= ~(SVFDONE|SKEEP); 404 } 405 u.u_procp->p_flag &= ~(SPAGI|SSEQL|SUANOM|SNUSIG); 406 u.u_procp->p_flag |= pagi; 407 u.u_dmap = u.u_cdmap; 408 u.u_smap = u.u_csmap; 409 vgetvm(ts, ds, ss); 410 411 if (pagi == 0) 412 u.u_error = 413 rdwri(UIO_READ, ip, 414 (char *)ctob(dptov(u.u_procp, 0)), 415 (int)u.u_exdata.ux_dsize, 416 (int)(sizeof(u.u_exdata)+u.u_exdata.ux_tsize), 417 0, (int *)0); 418 xalloc(ip, pagi); 419 if (pagi && u.u_procp->p_textp) 420 vinifod((struct fpte *)dptopte(u.u_procp, 0), 421 PG_FTEXT, u.u_procp->p_textp->x_iptr, 422 (long)(1 + ts/CLSIZE), (int)btoc(u.u_exdata.ux_dsize)); 423 424 #ifdef vax 425 /* THIS SHOULD BE DONE AT A LOWER LEVEL, IF AT ALL */ 426 #include "../vax/mtpr.h" /* XXX */ 427 mtpr(TBIA, 0); 428 #endif 429 430 if (u.u_error) 431 swkill(u.u_procp, "i/o error mapping pages"); 432 /* 433 * set SUID/SGID protections, if no tracing 434 */ 435 if ((u.u_procp->p_flag&STRC)==0) { 436 u.u_uid = uid; 437 u.u_procp->p_uid = uid; 438 u.u_gid = gid; 439 } else 440 psignal(u.u_procp, SIGTRAP); 441 u.u_tsize = ts; 442 u.u_dsize = ds; 443 u.u_ssize = ss; 444 bad: 445 return; 446 } 447 448 /* 449 * Clear registers on exec 450 */ 451 setregs() 452 { 453 register int (**rp)(); 454 register i; 455 long sigmask; 456 457 for (rp = &u.u_signal[1], sigmask = 1L; rp < &u.u_signal[NSIG]; 458 sigmask <<= 1, rp++) { 459 switch (*rp) { 460 461 case SIG_IGN: 462 case SIG_DFL: 463 case SIG_HOLD: 464 continue; 465 466 default: 467 /* 468 * Normal or deferring catch; revert to default. 469 */ 470 (void) spl6(); 471 *rp = SIG_DFL; 472 if ((int)*rp & 1) 473 u.u_procp->p_siga0 |= sigmask; 474 else 475 u.u_procp->p_siga0 &= ~sigmask; 476 if ((int)*rp & 2) 477 u.u_procp->p_siga1 |= sigmask; 478 else 479 u.u_procp->p_siga1 &= ~sigmask; 480 (void) spl0(); 481 continue; 482 } 483 } 484 #ifdef vax 485 /* 486 for (rp = &u.u_ar0[0]; rp < &u.u_ar0[16];) 487 *rp++ = 0; 488 */ 489 u.u_ar0[PC] = u.u_exdata.ux_entloc+2; 490 #endif 491 #ifdef sun 492 { register struct regs *r = (struct regs *)u.u_ar0; 493 for (i = 0; i < 8; i++) { 494 r->r_dreg[i] = 0; 495 if (&r->r_areg[i] != &r->r_sp) 496 r->r_areg[i] = 0; 497 } 498 r->r_sr = PSL_USERSET; 499 r->r_pc = u.u_exdata.ux_entloc; 500 } 501 #endif 502 for (i=0; i<NOFILE; i++) { 503 if (u.u_pofile[i]&UF_EXCLOSE) { 504 closef(u.u_ofile[i], 1, u.u_pofile[i]); 505 u.u_ofile[i] = NULL; 506 u.u_pofile[i] = 0; 507 } 508 u.u_pofile[i] &= ~UF_MAPPED; 509 } 510 511 /* 512 * Remember file name for accounting. 513 */ 514 u.u_acflag &= ~AFORK; 515 bcopy((caddr_t)u.u_dent.d_name, (caddr_t)u.u_comm, 516 (unsigned)(u.u_dent.d_namlen + 1)); 517 #ifdef sun 518 u.u_eosys = REALLYRETURN; 519 #endif 520 } 521 522 /* 523 * Exit system call: pass back caller's arg 524 */ 525 rexit() 526 { 527 register struct a { 528 int rval; 529 } *uap; 530 531 uap = (struct a *)u.u_ap; 532 exit((uap->rval & 0377) << 8); 533 } 534 535 /* 536 * Release resources. 537 * Save u. area for parent to look at. 538 * Enter zombie state. 539 * Wake up parent and init processes, 540 * and dispose of children. 541 */ 542 exit(rv) 543 { 544 register int i; 545 register struct proc *p, *q; 546 register int x; 547 struct mbuf *m = m_getclr(M_WAIT, MT_ZOMBIE); 548 549 #ifdef PGINPROF 550 vmsizmon(); 551 #endif 552 p = u.u_procp; 553 p->p_flag &= ~(STRC|SULOCK); 554 p->p_flag |= SWEXIT; 555 (void) spl6(); 556 if ((int)SIG_IGN & 1) 557 p->p_siga0 = ~0; 558 else 559 p->p_siga0 = 0; 560 if ((int)SIG_IGN & 2) 561 p->p_siga1 = ~0; 562 else 563 p->p_siga1 = 0; 564 (void) spl0(); 565 p->p_cpticks = 0; 566 p->p_pctcpu = 0; 567 for (i=0; i<NSIG; i++) 568 u.u_signal[i] = SIG_IGN; 569 untimeout(realitexpire, (caddr_t)p); 570 /* 571 * Release virtual memory. If we resulted from 572 * a vfork(), instead give the resources back to 573 * the parent. 574 */ 575 if ((p->p_flag & SVFORK) == 0) 576 vrelvm(); 577 else { 578 p->p_flag &= ~SVFORK; 579 wakeup((caddr_t)p); 580 while ((p->p_flag & SVFDONE) == 0) 581 sleep((caddr_t)p, PZERO - 1); 582 p->p_flag &= ~SVFDONE; 583 } 584 for (i = 0; i < NOFILE; i++) { 585 struct file *f; 586 int p; 587 588 f = u.u_ofile[i]; 589 u.u_ofile[i] = NULL; 590 p = u.u_pofile[i]; 591 u.u_pofile[i] = 0; 592 closef(f, 1, p); 593 } 594 ilock(u.u_cdir); 595 iput(u.u_cdir); 596 if (u.u_rdir) { 597 ilock(u.u_rdir); 598 iput(u.u_rdir); 599 } 600 u.u_rlimit[RLIMIT_FSIZE].rlim_cur = RLIM_INFINITY; 601 acct(); 602 #ifdef QUOTA 603 qclean(); 604 #endif 605 #ifdef sun 606 ctxfree(u.u_procp); 607 #endif 608 vrelpt(u.u_procp); 609 vrelu(u.u_procp, 0); 610 (void) spl5(); /* hack for mem alloc race XXX */ 611 multprog--; 612 p->p_stat = SZOMB; 613 noproc = 1; 614 i = PIDHASH(p->p_pid); 615 x = p - proc; 616 if (pidhash[i] == x) 617 pidhash[i] = p->p_idhash; 618 else { 619 for (i = pidhash[i]; i != 0; i = proc[i].p_idhash) 620 if (proc[i].p_idhash == x) { 621 proc[i].p_idhash = p->p_idhash; 622 goto done; 623 } 624 panic("exit"); 625 } 626 if (p->p_pid == 1) 627 panic("init died"); 628 done: 629 p->p_xstat = rv; 630 if (m == 0) 631 panic("exit: m_getclr"); 632 p->p_ru = mtod(m, struct rusage *); 633 *p->p_ru = u.u_ru; 634 ruadd(p->p_ru, &u.u_cru); 635 for (q = proc; q < procNPROC; q++) 636 if (q->p_pptr == p) { 637 if (q->p_osptr) 638 q->p_osptr->p_ysptr = q->p_ysptr; 639 if (q->p_ysptr) 640 q->p_ysptr->p_osptr = q->p_osptr; 641 if (proc[1].p_cptr) 642 proc[1].p_cptr->p_ysptr = q; 643 q->p_osptr = proc[1].p_cptr; 644 q->p_ysptr = NULL; 645 proc[1].p_cptr = q; 646 647 q->p_pptr = &proc[1]; 648 q->p_ppid = 1; 649 wakeup((caddr_t)&proc[1]); 650 /* 651 * Traced processes are killed 652 * since their existence means someone is screwing up. 653 * Stopped processes are sent a hangup and a continue. 654 * This is designed to be ``safe'' for setuid 655 * processes since they must be willing to tolerate 656 * hangups anyways. 657 */ 658 if (q->p_flag&STRC) { 659 q->p_flag &= ~STRC; 660 psignal(q, SIGKILL); 661 } else if (q->p_stat == SSTOP) { 662 psignal(q, SIGHUP); 663 psignal(q, SIGCONT); 664 } 665 /* 666 * Protect this process from future 667 * tty signals, clear TSTP/TTIN/TTOU if pending. 668 */ 669 (void) spgrp(q, -1); 670 } 671 psignal(p->p_pptr, SIGCHLD); 672 wakeup((caddr_t)p->p_pptr); 673 swtch(); 674 } 675 676 wait() 677 { 678 struct rusage ru, *rup; 679 680 if ((u.u_ar0[PS] & PSL_ALLCC) != PSL_ALLCC) { 681 u.u_error = wait1(0, (struct rusage *)0); 682 return; 683 } 684 rup = (struct rusage *)u.u_ar0[R1]; 685 u.u_error = wait1(u.u_ar0[R0], &ru); 686 if (u.u_error) 687 return; 688 (void) copyout((caddr_t)&ru, (caddr_t)rup, sizeof (struct rusage)); 689 } 690 691 #ifndef NOCOMPAT 692 #include "../h/vtimes.h" 693 694 owait() 695 { 696 struct rusage ru; 697 struct vtimes *vtp, avt; 698 699 if ((u.u_ar0[PS] & PSL_ALLCC) != PSL_ALLCC) { 700 u.u_error = wait1(0, (struct rusage *)0); 701 return; 702 } 703 vtp = (struct vtimes *)u.u_ar0[R1]; 704 u.u_error = wait1(u.u_ar0[R0], &ru); 705 if (u.u_error) 706 return; 707 getvtimes(&ru, &avt); 708 (void) copyout((caddr_t)&avt, (caddr_t)vtp, sizeof (struct vtimes)); 709 } 710 #endif 711 712 /* 713 * Wait system call. 714 * Search for a terminated (zombie) child, 715 * finally lay it to rest, and collect its status. 716 * Look also for stopped (traced) children, 717 * and pass back status from them. 718 */ 719 wait1(options, ru) 720 register int options; 721 struct rusage *ru; 722 { 723 register f; 724 register struct proc *p, *q; 725 726 f = 0; 727 loop: 728 for (p = proc; p < procNPROC; p++) 729 if (p->p_pptr == u.u_procp) { 730 f++; 731 if (p->p_stat == SZOMB) { 732 u.u_r.r_val1 = p->p_pid; 733 u.u_r.r_val2 = p->p_xstat; 734 p->p_xstat = 0; 735 if (ru) 736 *ru = *p->p_ru; 737 ruadd(&u.u_cru, p->p_ru); 738 (void) m_free(dtom(p->p_ru)); 739 p->p_ru = 0; 740 p->p_stat = NULL; 741 p->p_pid = 0; 742 p->p_ppid = 0; 743 if (q = p->p_ysptr) 744 q->p_osptr = p->p_osptr; 745 if (q = p->p_osptr) 746 q->p_ysptr = p->p_ysptr; 747 if ((q = p->p_pptr)->p_cptr == p) 748 q->p_cptr = p->p_osptr; 749 p->p_pptr = 0; 750 p->p_ysptr = 0; 751 p->p_osptr = 0; 752 p->p_cptr = 0; 753 p->p_sig = 0; 754 p->p_siga0 = 0; 755 p->p_siga1 = 0; 756 p->p_pgrp = 0; 757 p->p_flag = 0; 758 p->p_wchan = 0; 759 p->p_cursig = 0; 760 return (0); 761 } 762 if (p->p_stat == SSTOP && (p->p_flag&SWTED)==0 && 763 (p->p_flag&STRC || options&WUNTRACED)) { 764 p->p_flag |= SWTED; 765 u.u_r.r_val1 = p->p_pid; 766 u.u_r.r_val2 = (p->p_cursig<<8) | WSTOPPED; 767 return (0); 768 } 769 } 770 if (f == 0) { 771 return (ECHILD); 772 } 773 if (options&WNOHANG) { 774 u.u_r.r_val1 = 0; 775 return (0); 776 } 777 if ((u.u_procp->p_flag&SNUSIG) && setjmp(&u.u_qsave)) { 778 u.u_eosys = RESTARTSYS; 779 return (0); 780 } 781 sleep((caddr_t)u.u_procp, PWAIT); 782 goto loop; 783 } 784 785 /* 786 * fork system call. 787 */ 788 fork() 789 { 790 791 u.u_cdmap = zdmap; 792 u.u_csmap = zdmap; 793 if (swpexpand(u.u_dsize, u.u_ssize, &u.u_cdmap, &u.u_csmap) == 0) { 794 u.u_r.r_val2 = 0; 795 return; 796 } 797 fork1(0); 798 } 799 800 fork1(isvfork) 801 { 802 register struct proc *p1, *p2; 803 register a; 804 805 a = 0; 806 p2 = NULL; 807 for (p1 = proc; p1 < procNPROC; p1++) { 808 if (p1->p_stat==NULL && p2==NULL) 809 p2 = p1; 810 else { 811 if (p1->p_uid==u.u_uid && p1->p_stat!=NULL) 812 a++; 813 } 814 } 815 /* 816 * Disallow if 817 * No processes at all; 818 * not su and too many procs owned; or 819 * not su and would take last slot. 820 */ 821 if (p2==NULL) 822 tablefull("proc"); 823 if (p2==NULL || (u.u_uid!=0 && (p2==procNPROC-1 || a>MAXUPRC))) { 824 u.u_error = EAGAIN; 825 if (!isvfork) { 826 (void) vsexpand(0, &u.u_cdmap, 1); 827 (void) vsexpand(0, &u.u_csmap, 1); 828 } 829 goto out; 830 } 831 p1 = u.u_procp; 832 if (newproc(isvfork)) { 833 u.u_r.r_val1 = p1->p_pid; 834 u.u_r.r_val2 = 1; /* child */ 835 u.u_start = time.tv_sec; 836 u.u_acflag = AFORK; 837 return; 838 } 839 u.u_r.r_val1 = p2->p_pid; 840 841 out: 842 u.u_r.r_val2 = 0; 843 } 844 845 spgrp(top, npgrp) 846 register struct proc *top; 847 { 848 register struct proc *pp, *p; 849 int f = 0; 850 851 for (p = top; npgrp == -1 || u.u_uid == p->p_uid || 852 !u.u_uid || inferior(p); p = pp) { 853 if (npgrp == -1) { 854 #define bit(a) (1<<(a-1)) 855 p->p_sig &= ~(bit(SIGTSTP)|bit(SIGTTIN)|bit(SIGTTOU)); 856 } else 857 p->p_pgrp = npgrp; 858 f++; 859 /* 860 * Search for children. 861 */ 862 for (pp = proc; pp < procNPROC; pp++) 863 if (pp->p_pptr == p) 864 goto cont; 865 /* 866 * Search for siblings. 867 */ 868 for (; p != top; p = p->p_pptr) 869 for (pp = p + 1; pp < procNPROC; pp++) 870 if (pp->p_pptr == p->p_pptr) 871 goto cont; 872 break; 873 cont: 874 ; 875 } 876 return (f); 877 } 878 879 /* 880 * Is p an inferior of the current process? 881 */ 882 inferior(p) 883 register struct proc *p; 884 { 885 886 for (; p != u.u_procp; p = p->p_pptr) 887 if (p->p_ppid == 0) 888 return (0); 889 return (1); 890 } 891 892 struct proc * 893 pfind(pid) 894 int pid; 895 { 896 register struct proc *p; 897 898 for (p = &proc[pidhash[PIDHASH(pid)]]; p != &proc[0]; p = &proc[p->p_idhash]) 899 if (p->p_pid == pid) 900 return (p); 901 return ((struct proc *)0); 902 } 903 904 /* 905 * Create a new process-- the internal version of 906 * sys fork. 907 * It returns 1 in the new process, 0 in the old. 908 */ 909 newproc(isvfork) 910 int isvfork; 911 { 912 register struct proc *p; 913 register struct proc *rpp, *rip; 914 register int n; 915 register struct file *fp; 916 917 p = NULL; 918 /* 919 * First, just locate a slot for a process 920 * and copy the useful info from this process into it. 921 * The panic "cannot happen" because fork has already 922 * checked for the existence of a slot. 923 */ 924 retry: 925 mpid++; 926 if (mpid >= 30000) { 927 mpid = 0; 928 goto retry; 929 } 930 for (rpp = proc; rpp < procNPROC; rpp++) { 931 if (rpp->p_stat == NULL && p==NULL) 932 p = rpp; 933 if (rpp->p_pid==mpid || rpp->p_pgrp==mpid) 934 goto retry; 935 } 936 if ((rpp = p) == NULL) 937 panic("no procs"); 938 939 /* 940 * Make a proc table entry for the new process. 941 */ 942 rip = u.u_procp; 943 #ifdef QUOTA 944 rpp->p_quota = rip->p_quota; 945 rpp->p_quota->q_cnt++; 946 #endif 947 rpp->p_stat = SIDL; 948 timerclear(&rpp->p_realtimer.it_value); 949 rpp->p_flag = SLOAD | (rip->p_flag & (SPAGI|SNUSIG)); 950 if (isvfork) { 951 rpp->p_flag |= SVFORK; 952 rpp->p_ndx = rip->p_ndx; 953 } else 954 rpp->p_ndx = rpp - proc; 955 rpp->p_uid = rip->p_uid; 956 rpp->p_pgrp = rip->p_pgrp; 957 rpp->p_nice = rip->p_nice; 958 rpp->p_textp = isvfork ? 0 : rip->p_textp; 959 rpp->p_pid = mpid; 960 rpp->p_ppid = rip->p_pid; 961 rpp->p_pptr = rip; 962 rpp->p_osptr = rip->p_cptr; 963 if (rip->p_cptr) 964 rip->p_cptr->p_ysptr = rpp; 965 rpp->p_ysptr = NULL; 966 rpp->p_cptr = NULL; 967 rip->p_cptr = rpp; 968 rpp->p_time = 0; 969 rpp->p_cpu = 0; 970 rpp->p_siga0 = rip->p_siga0; 971 rpp->p_siga1 = rip->p_siga1; 972 /* take along any pending signals, like stops? */ 973 if (isvfork) { 974 rpp->p_tsize = rpp->p_dsize = rpp->p_ssize = 0; 975 rpp->p_szpt = clrnd(ctopt(UPAGES)); 976 forkstat.cntvfork++; 977 forkstat.sizvfork += rip->p_dsize + rip->p_ssize; 978 } else { 979 rpp->p_tsize = rip->p_tsize; 980 rpp->p_dsize = rip->p_dsize; 981 rpp->p_ssize = rip->p_ssize; 982 rpp->p_szpt = rip->p_szpt; 983 forkstat.cntfork++; 984 forkstat.sizfork += rip->p_dsize + rip->p_ssize; 985 } 986 rpp->p_rssize = 0; 987 rpp->p_maxrss = rip->p_maxrss; 988 rpp->p_wchan = 0; 989 rpp->p_slptime = 0; 990 rpp->p_pctcpu = 0; 991 rpp->p_cpticks = 0; 992 n = PIDHASH(rpp->p_pid); 993 p->p_idhash = pidhash[n]; 994 pidhash[n] = rpp - proc; 995 multprog++; 996 997 /* 998 * Increase reference counts on shared objects. 999 */ 1000 for (n = 0; n < NOFILE; n++) { 1001 fp = u.u_ofile[n]; 1002 if (fp == NULL) 1003 continue; 1004 fp->f_count++; 1005 if (u.u_pofile[n]&UF_SHLOCK) 1006 fp->f_inode->i_shlockc++; 1007 if (u.u_pofile[n]&UF_EXLOCK) 1008 fp->f_inode->i_exlockc++; 1009 } 1010 u.u_cdir->i_count++; 1011 if (u.u_rdir) 1012 u.u_rdir->i_count++; 1013 1014 /* 1015 * Partially simulate the environment 1016 * of the new process so that when it is actually 1017 * created (by copying) it will look right. 1018 * This begins the section where we must prevent the parent 1019 * from being swapped. 1020 */ 1021 rip->p_flag |= SKEEP; 1022 if (procdup(rpp, isvfork)) 1023 return (1); 1024 1025 /* 1026 * Make child runnable and add to run queue. 1027 */ 1028 (void) spl6(); 1029 rpp->p_stat = SRUN; 1030 setrq(rpp); 1031 (void) spl0(); 1032 1033 /* 1034 * Cause child to take a non-local goto as soon as it runs. 1035 * On older systems this was done with SSWAP bit in proc 1036 * table; on VAX we use u.u_pcb.pcb_sswap so don't need 1037 * to do rpp->p_flag |= SSWAP. Actually do nothing here. 1038 */ 1039 /* rpp->p_flag |= SSWAP; */ 1040 1041 /* 1042 * Now can be swapped. 1043 */ 1044 rip->p_flag &= ~SKEEP; 1045 1046 /* 1047 * If vfork make chain from parent process to child 1048 * (where virtal memory is temporarily). Wait for 1049 * child to finish, steal virtual memory back, 1050 * and wakeup child to let it die. 1051 */ 1052 if (isvfork) { 1053 u.u_procp->p_xlink = rpp; 1054 u.u_procp->p_flag |= SNOVM; 1055 while (rpp->p_flag & SVFORK) 1056 sleep((caddr_t)rpp, PZERO - 1); 1057 if ((rpp->p_flag & SLOAD) == 0) 1058 panic("newproc vfork"); 1059 uaccess(rpp, Vfmap, &vfutl); 1060 u.u_procp->p_xlink = 0; 1061 vpassvm(rpp, u.u_procp, &vfutl, &u, Vfmap); 1062 u.u_procp->p_flag &= ~SNOVM; 1063 rpp->p_ndx = rpp - proc; 1064 rpp->p_flag |= SVFDONE; 1065 wakeup((caddr_t)rpp); 1066 } 1067 1068 /* 1069 * 0 return means parent. 1070 */ 1071 return (0); 1072 } 1073