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