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