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