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