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