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