1 static char *sccsid = "@(#)proc.c 4.12 (Berkeley) 83/07/01"; 2 3 #include "sh.h" 4 #include "sh.dir.h" 5 #include "sh.proc.h" 6 #include <sys/wait.h> 7 #include <sys/ioctl.h> 8 9 /* 10 * C Shell - functions that manage processes, handling hanging, termination 11 */ 12 13 #define BIGINDEX 9 /* largest desirable job index */ 14 15 /* 16 * pchild - called at interrupt level by the SIGCHLD signal 17 * indicating that at least one child has terminated or stopped 18 * thus at least one wait system call will definitely return a 19 * childs status. Top level routines (like pwait) must be sure 20 * to mask interrupts when playing with the proclist data structures! 21 */ 22 pchild() 23 { 24 register struct process *pp; 25 register struct process *fp; 26 register int pid; 27 union wait w; 28 int jobflags; 29 struct rusage ru; 30 31 if (!timesdone) 32 timesdone++, times(&shtimes); 33 loop: 34 pid = wait3(&w.w_status, (setintr ? WNOHANG|WUNTRACED:WNOHANG), 35 &ru); 36 if (pid <= 0) { 37 if (errno == EINTR) { 38 errno = 0; 39 goto loop; 40 } 41 pnoprocesses = pid == -1; 42 return; 43 } 44 for (pp = proclist.p_next; pp != PNULL; pp = pp->p_next) 45 if (pid == pp->p_pid) 46 goto found; 47 goto loop; 48 found: 49 if (pid == atoi(value("child"))) 50 unsetv("child"); 51 pp->p_flags &= ~(PRUNNING|PSTOPPED|PREPORTED); 52 if (WIFSTOPPED(w)) { 53 pp->p_flags |= PSTOPPED; 54 pp->p_reason = w.w_stopsig; 55 } else { 56 if (pp->p_flags & (PTIME|PPTIME) || adrof("time")) { 57 time_t oldcutimes, oldcstimes; 58 oldcutimes = shtimes.tms_cutime; 59 oldcstimes = shtimes.tms_cstime; 60 gettimeofday(&pp->p_etime, (struct timezone *)0); 61 times(&shtimes); 62 pp->p_utime = shtimes.tms_cutime - oldcutimes; 63 pp->p_stime = shtimes.tms_cstime - oldcstimes; 64 } else 65 times(&shtimes); 66 pp->p_rusage = ru; 67 if (WIFSIGNALED(w)) { 68 if (w.w_termsig == SIGINT) 69 pp->p_flags |= PINTERRUPTED; 70 else 71 pp->p_flags |= PSIGNALED; 72 if (w.w_coredump) 73 pp->p_flags |= PDUMPED; 74 pp->p_reason = w.w_termsig; 75 } else { 76 pp->p_reason = w.w_retcode; 77 if (pp->p_reason != 0) 78 pp->p_flags |= PAEXITED; 79 else 80 pp->p_flags |= PNEXITED; 81 } 82 } 83 jobflags = 0; 84 fp = pp; 85 do { 86 if ((fp->p_flags & (PPTIME|PRUNNING|PSTOPPED)) == 0 && 87 !child && adrof("time") && 88 (fp->p_utime + fp->p_stime) / HZ >= 89 atoi(value("time"))) 90 fp->p_flags |= PTIME; 91 jobflags |= fp->p_flags; 92 } while ((fp = fp->p_friends) != pp); 93 pp->p_flags &= ~PFOREGND; 94 if (pp == pp->p_friends && (pp->p_flags & PPTIME)) { 95 pp->p_flags &= ~PPTIME; 96 pp->p_flags |= PTIME; 97 } 98 if ((jobflags & (PRUNNING|PREPORTED)) == 0) { 99 fp = pp; 100 do { 101 if (fp->p_flags&PSTOPPED) 102 fp->p_flags |= PREPORTED; 103 } while((fp = fp->p_friends) != pp); 104 while(fp->p_pid != fp->p_jobid) 105 fp = fp->p_friends; 106 if (jobflags&PSTOPPED) { 107 if (pcurrent && pcurrent != fp) 108 pprevious = pcurrent; 109 pcurrent = fp; 110 } else 111 pclrcurr(fp); 112 if (jobflags&PFOREGND) { 113 if (jobflags & (PSIGNALED|PSTOPPED|PPTIME) || 114 #ifdef IIASA 115 jobflags & PAEXITED || 116 #endif 117 !eq(dcwd->di_name, fp->p_cwd->di_name)) { 118 ; /* print in pjwait */ 119 } 120 /* 121 else if ((jobflags & (PTIME|PSTOPPED)) == PTIME) 122 ptprint(fp); 123 */ 124 } else { 125 if (jobflags&PNOTIFY || adrof("notify")) { 126 printf("\215\n"); 127 pprint(pp, NUMBER|NAME|REASON); 128 if ((jobflags&PSTOPPED) == 0) 129 pflush(pp); 130 } else { 131 fp->p_flags |= PNEEDNOTE; 132 neednote++; 133 } 134 } 135 } 136 goto loop; 137 } 138 139 pnote() 140 { 141 register struct process *pp; 142 int flags; 143 144 neednote = 0; 145 for (pp = proclist.p_next; pp != PNULL; pp = pp->p_next) { 146 if (pp->p_flags & PNEEDNOTE) { 147 sighold(SIGCHLD); 148 pp->p_flags &= ~PNEEDNOTE; 149 flags = pprint(pp, NUMBER|NAME|REASON); 150 if ((flags&(PRUNNING|PSTOPPED)) == 0) 151 pflush(pp); 152 sigrelse(SIGCHLD); 153 } 154 } 155 } 156 157 /* 158 * pwait - wait for current job to terminate, maintaining integrity 159 * of current and previous job indicators. 160 */ 161 pwait() 162 { 163 register struct process *fp, *pp; 164 165 /* 166 * Here's where dead procs get flushed. 167 */ 168 sighold(SIGCHLD); 169 for (pp = (fp = &proclist)->p_next; pp != PNULL; pp = (fp = pp)->p_next) 170 if (pp->p_pid == 0) { 171 fp->p_next = pp->p_next; 172 xfree(pp->p_command); 173 if (pp->p_cwd && --pp->p_cwd->di_count == 0) 174 if (pp->p_cwd->di_next == 0) 175 dfree(pp->p_cwd); 176 xfree((char *)pp); 177 pp = fp; 178 } 179 sigrelse(SIGCHLD); 180 if (setintr) 181 sigignore(SIGINT); 182 pjwait(pcurrjob); 183 } 184 185 /* 186 * pjwait - wait for a job to finish or become stopped 187 * It is assumed to be in the foreground state (PFOREGND) 188 */ 189 pjwait(pp) 190 register struct process *pp; 191 { 192 register struct process *fp; 193 int jobflags, reason; 194 195 while (pp->p_pid != pp->p_jobid) 196 pp = pp->p_friends; 197 fp = pp; 198 do { 199 if ((fp->p_flags&(PFOREGND|PRUNNING)) == PRUNNING) 200 printf("BUG: waiting for background job!\n"); 201 } while ((fp = fp->p_friends) != pp); 202 /* 203 * Now keep pausing as long as we are not interrupted (SIGINT), 204 * and the target process, or any of its friends, are running 205 */ 206 fp = pp; 207 for (;;) { 208 sighold(SIGCHLD); 209 jobflags = 0; 210 do 211 jobflags |= fp->p_flags; 212 while((fp = (fp->p_friends)) != pp); 213 if ((jobflags & PRUNNING) == 0) 214 break; 215 sigpause(sigblock(0) &~ mask(SIGCHLD)); 216 } 217 sigrelse(SIGCHLD); 218 if (tpgrp > 0) 219 ioctl(FSHTTY, TIOCSPGRP, &tpgrp); /* get tty back */ 220 if ((jobflags&(PSIGNALED|PSTOPPED|PTIME)) || 221 !eq(dcwd->di_name, fp->p_cwd->di_name)) { 222 if (jobflags&PSTOPPED) 223 printf("\n"); 224 pprint(pp, AREASON|SHELLDIR); 225 } 226 if ((jobflags&(PINTERRUPTED|PSTOPPED)) && setintr && 227 (!gointr || !eq(gointr, "-"))) { 228 if ((jobflags & PSTOPPED) == 0) 229 pflush(pp); 230 pintr1(0); 231 /*NOTREACHED*/ 232 } 233 reason = 0; 234 fp = pp; 235 do { 236 if (fp->p_reason) 237 reason = fp->p_flags & (PSIGNALED|PINTERRUPTED) ? 238 fp->p_reason | QUOTE : fp->p_reason; 239 } while ((fp = fp->p_friends) != pp); 240 set("status", putn(reason)); 241 if (reason && exiterr) 242 exitstat(); 243 pflush(pp); 244 } 245 246 /* 247 * dowait - wait for all processes to finish 248 */ 249 dowait() 250 { 251 register struct process *pp; 252 253 pjobs++; 254 if (setintr) 255 sigrelse(SIGINT); 256 loop: 257 sighold(SIGCHLD); 258 for (pp = proclist.p_next; pp; pp = pp->p_next) 259 if (pp->p_pid && /* pp->p_pid == pp->p_jobid && */ 260 pp->p_flags&PRUNNING) { 261 sigpause(sigblock(0) &~ mask(SIGCHLD)); 262 goto loop; 263 } 264 sigrelse(SIGCHLD); 265 pjobs = 0; 266 } 267 268 /* 269 * pflushall - flush all jobs from list (e.g. at fork()) 270 */ 271 pflushall() 272 { 273 register struct process *pp; 274 275 for (pp = proclist.p_next; pp != PNULL; pp = pp->p_next) 276 if (pp->p_pid) 277 pflush(pp); 278 } 279 280 /* 281 * pflush - flag all process structures in the same job as the 282 * the argument process for deletion. The actual free of the 283 * space is not done here since pflush is called at interrupt level. 284 */ 285 pflush(pp) 286 register struct process *pp; 287 { 288 register struct process *np; 289 register int index; 290 291 if (pp->p_pid == 0) { 292 printf("BUG: process flushed twice"); 293 return; 294 } 295 while (pp->p_pid != pp->p_jobid) 296 pp = pp->p_friends; 297 pclrcurr(pp); 298 if (pp == pcurrjob) 299 pcurrjob = 0; 300 index = pp->p_index; 301 np = pp; 302 do { 303 np->p_index = np->p_pid = 0; 304 np->p_flags &= ~PNEEDNOTE; 305 } while ((np = np->p_friends) != pp); 306 if (index == pmaxindex) { 307 for (np = proclist.p_next, index = 0; np; np = np->p_next) 308 if (np->p_index > index) 309 index = np->p_index; 310 pmaxindex = index; 311 } 312 } 313 314 /* 315 * pclrcurr - make sure the given job is not the current or previous job; 316 * pp MUST be the job leader 317 */ 318 pclrcurr(pp) 319 register struct process *pp; 320 { 321 322 if (pp == pcurrent) 323 if (pprevious != PNULL) { 324 pcurrent = pprevious; 325 pprevious = pgetcurr(pp); 326 } else { 327 pcurrent = pgetcurr(pp); 328 pprevious = pgetcurr(pp); 329 } 330 else if (pp == pprevious) 331 pprevious = pgetcurr(pp); 332 } 333 334 /* +4 here is 1 for '\0', 1 ea for << >& >> */ 335 char command[PMAXLEN+4]; 336 int cmdlen; 337 char *cmdp; 338 /* 339 * palloc - allocate a process structure and fill it up. 340 * an important assumption is made that the process is running. 341 */ 342 palloc(pid, t) 343 int pid; 344 register struct command *t; 345 { 346 register struct process *pp; 347 int i; 348 349 pp = (struct process *)calloc(1, sizeof(struct process)); 350 pp->p_pid = pid; 351 pp->p_flags = t->t_dflg & FAND ? PRUNNING : PRUNNING|PFOREGND; 352 if (t->t_dflg & FTIME) 353 pp->p_flags |= PPTIME; 354 cmdp = command; 355 cmdlen = 0; 356 padd(t); 357 *cmdp++ = 0; 358 if (t->t_dflg & FPOU) { 359 pp->p_flags |= PPOU; 360 if (t->t_dflg & FDIAG) 361 pp->p_flags |= PDIAG; 362 } 363 pp->p_command = savestr(command); 364 if (pcurrjob) { 365 struct process *fp; 366 /* careful here with interrupt level */ 367 pp->p_cwd = 0; 368 pp->p_index = pcurrjob->p_index; 369 pp->p_friends = pcurrjob; 370 pp->p_jobid = pcurrjob->p_pid; 371 for (fp = pcurrjob; fp->p_friends != pcurrjob; fp = fp->p_friends) 372 ; 373 fp->p_friends = pp; 374 } else { 375 pcurrjob = pp; 376 pp->p_jobid = pid; 377 pp->p_friends = pp; 378 pp->p_cwd = dcwd; 379 dcwd->di_count++; 380 if (pmaxindex < BIGINDEX) 381 pp->p_index = ++pmaxindex; 382 else { 383 struct process *np; 384 385 for (i = 1; ; i++) { 386 for (np = proclist.p_next; np; np = np->p_next) 387 if (np->p_index == i) 388 goto tryagain; 389 pp->p_index = i; 390 if (i > pmaxindex) 391 pmaxindex = i; 392 break; 393 tryagain:; 394 } 395 } 396 if (pcurrent == PNULL) 397 pcurrent = pp; 398 else if (pprevious == PNULL) 399 pprevious = pp; 400 } 401 pp->p_next = proclist.p_next; 402 proclist.p_next = pp; 403 gettimeofday(&pp->p_btime, (struct timezone *)0); 404 } 405 406 padd(t) 407 register struct command *t; 408 { 409 char **argp; 410 411 if (t == 0) 412 return; 413 switch (t->t_dtyp) { 414 415 case TPAR: 416 pads("( "); 417 padd(t->t_dspr); 418 pads(" )"); 419 break; 420 421 case TCOM: 422 for (argp = t->t_dcom; *argp; argp++) { 423 pads(*argp); 424 if (argp[1]) 425 pads(" "); 426 } 427 break; 428 429 case TFIL: 430 padd(t->t_dcar); 431 pads(" | "); 432 padd(t->t_dcdr); 433 return; 434 435 case TLST: 436 padd(t->t_dcar); 437 pads("; "); 438 padd(t->t_dcdr); 439 return; 440 } 441 if ((t->t_dflg & FPIN) == 0 && t->t_dlef) { 442 pads((t->t_dflg & FHERE) ? " << " : " < "); 443 pads(t->t_dlef); 444 } 445 if ((t->t_dflg & FPOU) == 0 && t->t_drit) { 446 pads((t->t_dflg & FCAT) ? " >>" : " >"); 447 if (t->t_dflg & FDIAG) 448 pads("&"); 449 pads(" "); 450 pads(t->t_drit); 451 } 452 } 453 454 pads(cp) 455 char *cp; 456 { 457 register int i = strlen(cp); 458 459 if (cmdlen >= PMAXLEN) 460 return; 461 if (cmdlen + i >= PMAXLEN) { 462 strcpy(cmdp, " ..."); 463 cmdlen = PMAXLEN; 464 cmdp += 4; 465 return; 466 } 467 strcpy(cmdp, cp); 468 cmdp += i; 469 cmdlen += i; 470 } 471 472 /* 473 * psavejob - temporarily save the current job on a one level stack 474 * so another job can be created. Used for { } in exp6 475 * and `` in globbing. 476 */ 477 psavejob() 478 { 479 480 pholdjob = pcurrjob; 481 pcurrjob = PNULL; 482 } 483 484 /* 485 * prestjob - opposite of psavejob. This may be missed if we are interrupted 486 * somewhere, but pendjob cleans up anyway. 487 */ 488 prestjob() 489 { 490 491 pcurrjob = pholdjob; 492 pholdjob = PNULL; 493 } 494 495 /* 496 * pendjob - indicate that a job (set of commands) has been completed 497 * or is about to begin. 498 */ 499 pendjob() 500 { 501 register struct process *pp, *tp; 502 503 if (pcurrjob && (pcurrjob->p_flags&(PFOREGND|PSTOPPED)) == 0) { 504 pp = pcurrjob; 505 while (pp->p_pid != pp->p_jobid) 506 pp = pp->p_friends; 507 printf("[%d]", pp->p_index); 508 tp = pp; 509 do { 510 printf(" %d", pp->p_pid); 511 pp = pp->p_friends; 512 } while (pp != tp); 513 printf("\n"); 514 } 515 pholdjob = pcurrjob = 0; 516 } 517 518 /* 519 * pprint - print a job 520 */ 521 pprint(pp, flag) 522 register struct process *pp; 523 { 524 register status, reason; 525 struct process *tp; 526 extern char *linp, linbuf[]; 527 int jobflags, pstatus; 528 char *format; 529 530 while (pp->p_pid != pp->p_jobid) 531 pp = pp->p_friends; 532 if (pp == pp->p_friends && (pp->p_flags & PPTIME)) { 533 pp->p_flags &= ~PPTIME; 534 pp->p_flags |= PTIME; 535 } 536 tp = pp; 537 status = reason = -1; 538 jobflags = 0; 539 do { 540 jobflags |= pp->p_flags; 541 pstatus = pp->p_flags & PALLSTATES; 542 if (tp != pp && linp != linbuf && !(flag&FANCY) && 543 (pstatus == status && pp->p_reason == reason || 544 !(flag&REASON))) 545 printf(" "); 546 else { 547 if (tp != pp && linp != linbuf) 548 printf("\n"); 549 if(flag&NUMBER) 550 if (pp == tp) 551 printf("[%d]%s %c ", pp->p_index, 552 pp->p_index < 10 ? " " : "", 553 pp==pcurrent ? '+' : 554 (pp == pprevious ? '-' : ' ')); 555 else 556 printf(" "); 557 if (flag&FANCY) 558 printf("%5d ", pp->p_pid); 559 if (flag&(REASON|AREASON)) { 560 if (flag&NAME) 561 format = "%-21s"; 562 else 563 format = "%s"; 564 if (pstatus == status) 565 if (pp->p_reason == reason) { 566 printf(format, ""); 567 goto prcomd; 568 } else 569 reason = pp->p_reason; 570 else { 571 status = pstatus; 572 reason = pp->p_reason; 573 } 574 switch (status) { 575 576 case PRUNNING: 577 printf(format, "Running "); 578 break; 579 580 case PINTERRUPTED: 581 case PSTOPPED: 582 case PSIGNALED: 583 if (flag&REASON || reason != SIGINT || 584 reason != SIGPIPE) 585 printf(format, mesg[pp->p_reason].pname); 586 break; 587 588 case PNEXITED: 589 case PAEXITED: 590 if (flag & REASON) 591 if (pp->p_reason) 592 printf("Exit %-16d", pp->p_reason); 593 else 594 printf(format, "Done"); 595 break; 596 597 default: 598 printf("BUG: status=%-9o", status); 599 } 600 } 601 } 602 prcomd: 603 if (flag&NAME) { 604 printf("%s", pp->p_command); 605 if (pp->p_flags & PPOU) 606 printf(" |"); 607 if (pp->p_flags & PDIAG) 608 printf("&"); 609 } 610 if (flag&(REASON|AREASON) && pp->p_flags&PDUMPED) 611 printf(" (core dumped)"); 612 if (tp == pp->p_friends) { 613 if (flag&ERSAND) 614 printf(" &"); 615 if (flag&JOBDIR && 616 !eq(tp->p_cwd->di_name, dcwd->di_name)) { 617 printf(" (wd: "); 618 dtildepr(value("home"), tp->p_cwd->di_name); 619 printf(")"); 620 } 621 } 622 if (pp->p_flags&PPTIME && !(status&(PSTOPPED|PRUNNING))) { 623 if (linp != linbuf) 624 printf("\n\t"); 625 { static struct rusage zru; 626 prusage(&zru, &pp->p_rusage, &pp->p_etime, 627 &pp->p_btime); 628 } 629 } 630 if (tp == pp->p_friends) { 631 if (linp != linbuf) 632 printf("\n"); 633 if (flag&SHELLDIR && !eq(tp->p_cwd->di_name, dcwd->di_name)) { 634 printf("(wd now: "); 635 dtildepr(value("home"), dcwd->di_name); 636 printf(")\n"); 637 } 638 } 639 } while ((pp = pp->p_friends) != tp); 640 if (jobflags&PTIME && (jobflags&(PSTOPPED|PRUNNING)) == 0) { 641 if (jobflags & NUMBER) 642 printf(" "); 643 ptprint(tp); 644 } 645 return (jobflags); 646 } 647 648 ptprint(tp) 649 register struct process *tp; 650 { 651 struct timeval tetime, diff; 652 static struct timeval ztime; 653 struct rusage ru; 654 static struct rusage zru; 655 register struct process *pp = tp; 656 657 ru = zru; 658 tetime = ztime; 659 do { 660 ruadd(&ru, &pp->p_rusage); 661 tvsub(&diff, &pp->p_etime, &pp->p_btime); 662 if (timercmp(&diff, &tetime, >)) 663 tetime = diff; 664 } while ((pp = pp->p_friends) != tp); 665 prusage(&zru, &ru, &tetime, &ztime); 666 } 667 668 /* 669 * dojobs - print all jobs 670 */ 671 dojobs(v) 672 char **v; 673 { 674 register struct process *pp; 675 register int flag = NUMBER|NAME|REASON; 676 int i; 677 678 if (chkstop) 679 chkstop = 2; 680 if (*++v) { 681 if (v[1] || !eq(*v, "-l")) 682 error("Usage: jobs [ -l ]"); 683 flag |= FANCY|JOBDIR; 684 } 685 for (i = 1; i <= pmaxindex; i++) 686 for (pp = proclist.p_next; pp; pp = pp->p_next) 687 if (pp->p_index == i && pp->p_pid == pp->p_jobid) { 688 pp->p_flags &= ~PNEEDNOTE; 689 if (!(pprint(pp, flag) & (PRUNNING|PSTOPPED))) 690 pflush(pp); 691 break; 692 } 693 } 694 695 /* 696 * dofg - builtin - put the job into the foreground 697 */ 698 dofg(v) 699 char **v; 700 { 701 register struct process *pp; 702 703 okpcntl(); 704 ++v; 705 do { 706 pp = pfind(*v); 707 pstart(pp, 1); 708 if (setintr) 709 sigignore(SIGINT); 710 pjwait(pp); 711 } while (*v && *++v); 712 } 713 714 /* 715 * %... - builtin - put the job into the foreground 716 */ 717 dofg1(v) 718 char **v; 719 { 720 register struct process *pp; 721 722 okpcntl(); 723 pp = pfind(v[0]); 724 pstart(pp, 1); 725 if (setintr) 726 sigignore(SIGINT); 727 pjwait(pp); 728 } 729 730 /* 731 * dobg - builtin - put the job into the background 732 */ 733 dobg(v) 734 char **v; 735 { 736 register struct process *pp; 737 738 okpcntl(); 739 ++v; 740 do { 741 pp = pfind(*v); 742 pstart(pp, 0); 743 } while (*v && *++v); 744 } 745 746 /* 747 * %... & - builtin - put the job into the background 748 */ 749 dobg1(v) 750 char **v; 751 { 752 register struct process *pp; 753 754 pp = pfind(v[0]); 755 pstart(pp, 0); 756 } 757 758 /* 759 * dostop - builtin - stop the job 760 */ 761 dostop(v) 762 char **v; 763 { 764 765 pkill(++v, SIGSTOP); 766 } 767 768 /* 769 * dokill - builtin - superset of kill (1) 770 */ 771 dokill(v) 772 char **v; 773 { 774 register int signum; 775 register char *name; 776 777 v++; 778 if (v[0] && v[0][0] == '-') { 779 if (v[0][1] == 'l') { 780 for (signum = 1; signum <= NSIG; signum++) { 781 if (name = mesg[signum].iname) 782 printf("%s ", name); 783 if (signum == 16) 784 printf("\n"); 785 } 786 printf("\n"); 787 return; 788 } 789 if (digit(v[0][1])) { 790 signum = atoi(v[0]+1); 791 if (signum < 1 || signum > NSIG) 792 bferr("Bad signal number"); 793 } else { 794 name = &v[0][1]; 795 for (signum = 1; signum <= NSIG; signum++) 796 if (mesg[signum].iname && 797 eq(name, mesg[signum].iname)) 798 goto gotsig; 799 setname(name); 800 bferr("Unknown signal; kill -l lists signals"); 801 } 802 gotsig: 803 v++; 804 } else 805 signum = SIGTERM; 806 pkill(v, signum); 807 } 808 809 pkill(v, signum) 810 char **v; 811 int signum; 812 { 813 register struct process *pp, *np; 814 register int jobflags = 0; 815 int pid; 816 char *cp; 817 extern char *sys_errlist[]; 818 int err = 0; 819 820 if (setintr) 821 sighold(SIGINT); 822 sighold(SIGCHLD); 823 while (*v) { 824 cp = globone(*v); 825 if (*cp == '%') { 826 np = pp = pfind(cp); 827 do 828 jobflags |= np->p_flags; 829 while ((np = np->p_friends) != pp); 830 switch (signum) { 831 832 case SIGSTOP: 833 case SIGTSTP: 834 case SIGTTIN: 835 case SIGTTOU: 836 if ((jobflags & PRUNNING) == 0) { 837 printf("%s: Already stopped\n", cp); 838 err++; 839 goto cont; 840 } 841 } 842 killpg(pp->p_jobid, signum); 843 if (signum == SIGTERM || signum == SIGHUP) 844 killpg(pp->p_jobid, SIGCONT); 845 } else if (!digit(*cp)) 846 bferr("Arguments should be jobs or process id's"); 847 else { 848 pid = atoi(cp); 849 if (kill(pid, signum) < 0) { 850 printf("%d: ", pid); 851 printf("%s\n", sys_errlist[errno]); 852 err++; 853 goto cont; 854 } 855 if (signum == SIGTERM || signum == SIGHUP) 856 kill(pid, SIGCONT); 857 } 858 cont: 859 xfree(cp); 860 v++; 861 } 862 sigrelse(SIGCHLD); 863 if (setintr) 864 sigrelse(SIGINT); 865 if (err) 866 error(NOSTR); 867 } 868 869 /* 870 * pstart - start the job in foreground/background 871 */ 872 pstart(pp, foregnd) 873 register struct process *pp; 874 int foregnd; 875 { 876 register struct process *np; 877 int jobflags = 0; 878 879 sighold(SIGCHLD); 880 np = pp; 881 do { 882 jobflags |= np->p_flags; 883 if (np->p_flags&(PRUNNING|PSTOPPED)) { 884 np->p_flags |= PRUNNING; 885 np->p_flags &= ~PSTOPPED; 886 if (foregnd) 887 np->p_flags |= PFOREGND; 888 else 889 np->p_flags &= ~PFOREGND; 890 } 891 } while((np = np->p_friends) != pp); 892 if (!foregnd) 893 pclrcurr(pp); 894 pprint(pp, foregnd ? NAME|JOBDIR : NUMBER|NAME|AMPERSAND); 895 if (foregnd) 896 ioctl(FSHTTY, TIOCSPGRP, &pp->p_jobid); 897 if (jobflags&PSTOPPED) 898 killpg(pp->p_jobid, SIGCONT); 899 sigrelse(SIGCHLD); 900 } 901 902 panystop(neednl) 903 { 904 register struct process *pp; 905 906 chkstop = 2; 907 for (pp = proclist.p_next; pp; pp = pp->p_next) 908 if (pp->p_flags & PSTOPPED) 909 error("\nThere are stopped jobs" + 1 - neednl); 910 } 911 912 struct process * 913 pfind(cp) 914 char *cp; 915 { 916 register struct process *pp, *np; 917 918 if (cp == 0 || cp[1] == 0 || eq(cp, "%%") || eq(cp, "%+")) { 919 if (pcurrent == PNULL) 920 bferr("No current job"); 921 return (pcurrent); 922 } 923 if (eq(cp, "%-") || eq(cp, "%#")) { 924 if (pprevious == PNULL) 925 bferr("No previous job"); 926 return (pprevious); 927 } 928 if (digit(cp[1])) { 929 int index = atoi(cp+1); 930 for (pp = proclist.p_next; pp; pp = pp->p_next) 931 if (pp->p_index == index && pp->p_pid == pp->p_jobid) 932 return (pp); 933 bferr("No such job"); 934 } 935 np = PNULL; 936 for (pp = proclist.p_next; pp; pp = pp->p_next) 937 if (pp->p_pid == pp->p_jobid) { 938 if (cp[1] == '?') { 939 register char *dp; 940 for (dp = pp->p_command; *dp; dp++) { 941 if (*dp != cp[2]) 942 continue; 943 if (prefix(cp+2, dp)) 944 goto match; 945 } 946 } else if (prefix(cp+1, pp->p_command)) { 947 match: 948 if (np) 949 bferr("Ambiguous"); 950 np = pp; 951 } 952 } 953 if (np) 954 return (np); 955 if (cp[1] == '?') 956 bferr("No job matches pattern"); 957 else 958 bferr("No such job"); 959 } 960 961 /* 962 * pgetcurr - find most recent job that is not pp, preferably stopped 963 */ 964 struct process * 965 pgetcurr(pp) 966 register struct process *pp; 967 { 968 register struct process *np; 969 register struct process *xp = PNULL; 970 971 for (np = proclist.p_next; np; np = np->p_next) 972 if (np != pcurrent && np != pp && np->p_pid && 973 np->p_pid == np->p_jobid) { 974 if (np->p_flags & PSTOPPED) 975 return (np); 976 if (xp == PNULL) 977 xp = np; 978 } 979 return (xp); 980 } 981 982 /* 983 * donotify - flag the job so as to report termination asynchronously 984 */ 985 donotify(v) 986 char **v; 987 { 988 register struct process *pp; 989 990 pp = pfind(*++v); 991 pp->p_flags |= PNOTIFY; 992 } 993 994 /* 995 * Do the fork and whatever should be done in the child side that 996 * should not be done if we are not forking at all (like for simple builtin's) 997 * Also do everything that needs any signals fiddled with in the parent side 998 * 999 * Wanttty tells whether process and/or tty pgrps are to be manipulated: 1000 * -1: leave tty alone; inherit pgrp from parent 1001 * 0: already have tty; manipulate process pgrps only 1002 * 1: want to claim tty; manipulate process and tty pgrps 1003 * It is usually just the value of tpgrp. 1004 */ 1005 pfork(t, wanttty) 1006 struct command *t; /* command we are forking for */ 1007 int wanttty; 1008 { 1009 register int pid; 1010 bool ignint = 0; 1011 int pgrp; 1012 1013 /* 1014 * A child will be uninterruptible only under very special 1015 * conditions. Remember that the semantics of '&' is 1016 * implemented by disconnecting the process from the tty so 1017 * signals do not need to ignored just for '&'. 1018 * Thus signals are set to default action for children unless: 1019 * we have had an "onintr -" (then specifically ignored) 1020 * we are not playing with signals (inherit action) 1021 */ 1022 if (setintr) 1023 ignint = (tpgrp == -1 && (t->t_dflg&FINT)) 1024 || (gointr && eq(gointr, "-")); 1025 /* 1026 * Hold SIGCHLD until we have the process installed in our table. 1027 */ 1028 sighold(SIGCHLD); 1029 while ((pid = fork()) < 0) 1030 if (setintr == 0) 1031 sleep(FORKSLEEP); 1032 else { 1033 sigrelse(SIGINT); 1034 sigrelse(SIGCHLD); 1035 error("No more processes"); 1036 } 1037 if (pid == 0) { 1038 settimes(); 1039 pgrp = pcurrjob ? pcurrjob->p_jobid : getpid(); 1040 pflushall(); 1041 pcurrjob = PNULL; 1042 timesdone = 0; 1043 child++; 1044 if (setintr) { 1045 setintr = 0; /* until I think otherwise */ 1046 sigrelse(SIGCHLD); 1047 /* 1048 * Children just get blown away on SIGINT, SIGQUIT 1049 * unless "onintr -" seen. 1050 */ 1051 signal(SIGINT, ignint ? SIG_IGN : SIG_DFL); 1052 signal(SIGQUIT, ignint ? SIG_IGN : SIG_DFL); 1053 if (wanttty >= 0) { 1054 /* make stoppable */ 1055 signal(SIGTSTP, SIG_DFL); 1056 signal(SIGTTIN, SIG_DFL); 1057 signal(SIGTTOU, SIG_DFL); 1058 } 1059 signal(SIGTERM, parterm); 1060 } else if (tpgrp == -1 && (t->t_dflg&FINT)) { 1061 signal(SIGINT, SIG_IGN); 1062 signal(SIGQUIT, SIG_IGN); 1063 } 1064 if (wanttty > 0) 1065 ioctl(FSHTTY, TIOCSPGRP, &pgrp); 1066 if (wanttty >= 0 && tpgrp >= 0) 1067 setpgrp(0, pgrp); 1068 if (tpgrp > 0) 1069 tpgrp = 0; /* gave tty away */ 1070 /* 1071 * Nohup and nice apply only to TCOM's but it would be 1072 * nice (?!?) if you could say "nohup (foo;bar)" 1073 * Then the parser would have to know about nice/nohup/time 1074 */ 1075 if (t->t_dflg & FNOHUP) 1076 signal(SIGHUP, SIG_IGN); 1077 if (t->t_dflg & FNICE) { 1078 /* sigh... 1079 nice(20); 1080 nice(-10); 1081 */ 1082 nice(t->t_nice); 1083 } 1084 1085 } else { 1086 palloc(pid, t); 1087 sigrelse(SIGCHLD); 1088 } 1089 1090 return (pid); 1091 } 1092 1093 okpcntl() 1094 { 1095 1096 if (tpgrp == -1) 1097 error("No job control in this shell"); 1098 if (tpgrp == 0) 1099 error("No job control in subshells"); 1100 } 1101