1 /*- 2 * Copyright (c) 1991, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * This code is derived from software contributed to Berkeley by 6 * Kenneth Almquist. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 4. Neither the name of the University nor the names of its contributors 17 * may be used to endorse or promote products derived from this software 18 * without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30 * SUCH DAMAGE. 31 */ 32 33 #ifndef lint 34 #if 0 35 static char sccsid[] = "@(#)jobs.c 8.5 (Berkeley) 5/4/95"; 36 #endif 37 #endif /* not lint */ 38 #include <sys/cdefs.h> 39 __FBSDID("$FreeBSD$"); 40 41 #include <sys/ioctl.h> 42 #include <sys/param.h> 43 #include <sys/resource.h> 44 #include <sys/time.h> 45 #include <sys/wait.h> 46 #include <errno.h> 47 #include <fcntl.h> 48 #include <paths.h> 49 #include <signal.h> 50 #include <stddef.h> 51 #include <stdlib.h> 52 #include <unistd.h> 53 54 #include "shell.h" 55 #if JOBS 56 #include <termios.h> 57 #undef CEOF /* syntax.h redefines this */ 58 #endif 59 #include "redir.h" 60 #include "exec.h" 61 #include "show.h" 62 #include "main.h" 63 #include "parser.h" 64 #include "nodes.h" 65 #include "jobs.h" 66 #include "options.h" 67 #include "trap.h" 68 #include "syntax.h" 69 #include "input.h" 70 #include "output.h" 71 #include "memalloc.h" 72 #include "error.h" 73 #include "mystring.h" 74 #include "var.h" 75 #include "builtins.h" 76 77 78 static struct job *jobtab; /* array of jobs */ 79 static int njobs; /* size of array */ 80 MKINIT pid_t backgndpid = -1; /* pid of last background process */ 81 MKINIT struct job *bgjob = NULL; /* last background process */ 82 #if JOBS 83 static struct job *jobmru; /* most recently used job list */ 84 static pid_t initialpgrp; /* pgrp of shell on invocation */ 85 #endif 86 int in_waitcmd = 0; /* are we in waitcmd()? */ 87 volatile sig_atomic_t breakwaitcmd = 0; /* should wait be terminated? */ 88 static int ttyfd = -1; 89 90 /* mode flags for dowait */ 91 #define DOWAIT_BLOCK 0x1 /* wait until a child exits */ 92 #define DOWAIT_SIG 0x2 /* if DOWAIT_BLOCK, abort on signals */ 93 94 #if JOBS 95 static void restartjob(struct job *); 96 #endif 97 static void freejob(struct job *); 98 static struct job *getjob(char *); 99 pid_t getjobpgrp(char *); 100 static pid_t dowait(int, struct job *); 101 static void checkzombies(void); 102 static void cmdtxt(union node *); 103 static void cmdputs(const char *); 104 #if JOBS 105 static void setcurjob(struct job *); 106 static void deljob(struct job *); 107 static struct job *getcurjob(struct job *); 108 #endif 109 static void printjobcmd(struct job *); 110 static void showjob(struct job *, int); 111 112 113 /* 114 * Turn job control on and off. 115 */ 116 117 MKINIT int jobctl; 118 119 #if JOBS 120 void 121 setjobctl(int on) 122 { 123 int i; 124 125 if (on == jobctl || rootshell == 0) 126 return; 127 if (on) { 128 if (ttyfd != -1) 129 close(ttyfd); 130 if ((ttyfd = open(_PATH_TTY, O_RDWR)) < 0) { 131 i = 0; 132 while (i <= 2 && !isatty(i)) 133 i++; 134 if (i > 2 || (ttyfd = fcntl(i, F_DUPFD, 10)) < 0) 135 goto out; 136 } 137 if (ttyfd < 10) { 138 /* 139 * Keep our TTY file descriptor out of the way of 140 * the user's redirections. 141 */ 142 if ((i = fcntl(ttyfd, F_DUPFD, 10)) < 0) { 143 close(ttyfd); 144 ttyfd = -1; 145 goto out; 146 } 147 close(ttyfd); 148 ttyfd = i; 149 } 150 if (fcntl(ttyfd, F_SETFD, FD_CLOEXEC) < 0) { 151 close(ttyfd); 152 ttyfd = -1; 153 goto out; 154 } 155 do { /* while we are in the background */ 156 initialpgrp = tcgetpgrp(ttyfd); 157 if (initialpgrp < 0) { 158 out: out2fmt_flush("sh: can't access tty; job control turned off\n"); 159 mflag = 0; 160 return; 161 } 162 if (initialpgrp != getpgrp()) { 163 kill(0, SIGTTIN); 164 continue; 165 } 166 } while (0); 167 setsignal(SIGTSTP); 168 setsignal(SIGTTOU); 169 setsignal(SIGTTIN); 170 setpgid(0, rootpid); 171 tcsetpgrp(ttyfd, rootpid); 172 } else { /* turning job control off */ 173 setpgid(0, initialpgrp); 174 tcsetpgrp(ttyfd, initialpgrp); 175 close(ttyfd); 176 ttyfd = -1; 177 setsignal(SIGTSTP); 178 setsignal(SIGTTOU); 179 setsignal(SIGTTIN); 180 } 181 jobctl = on; 182 } 183 #endif 184 185 186 #if JOBS 187 int 188 fgcmd(int argc __unused, char **argv) 189 { 190 struct job *jp; 191 pid_t pgrp; 192 int status; 193 194 jp = getjob(argv[1]); 195 if (jp->jobctl == 0) 196 error("job not created under job control"); 197 printjobcmd(jp); 198 flushout(&output); 199 pgrp = jp->ps[0].pid; 200 tcsetpgrp(ttyfd, pgrp); 201 restartjob(jp); 202 jp->foreground = 1; 203 INTOFF; 204 status = waitforjob(jp, (int *)NULL); 205 INTON; 206 return status; 207 } 208 209 210 int 211 bgcmd(int argc, char **argv) 212 { 213 struct job *jp; 214 215 do { 216 jp = getjob(*++argv); 217 if (jp->jobctl == 0) 218 error("job not created under job control"); 219 if (jp->state == JOBDONE) 220 continue; 221 restartjob(jp); 222 jp->foreground = 0; 223 out1fmt("[%td] ", jp - jobtab + 1); 224 printjobcmd(jp); 225 } while (--argc > 1); 226 return 0; 227 } 228 229 230 static void 231 restartjob(struct job *jp) 232 { 233 struct procstat *ps; 234 int i; 235 236 if (jp->state == JOBDONE) 237 return; 238 setcurjob(jp); 239 INTOFF; 240 kill(-jp->ps[0].pid, SIGCONT); 241 for (ps = jp->ps, i = jp->nprocs ; --i >= 0 ; ps++) { 242 if (WIFSTOPPED(ps->status)) { 243 ps->status = -1; 244 jp->state = 0; 245 } 246 } 247 INTON; 248 } 249 #endif 250 251 252 int 253 jobscmd(int argc __unused, char *argv[] __unused) 254 { 255 char *id; 256 int ch, mode; 257 258 mode = SHOWJOBS_DEFAULT; 259 while ((ch = nextopt("lps")) != '\0') { 260 switch (ch) { 261 case 'l': 262 mode = SHOWJOBS_VERBOSE; 263 break; 264 case 'p': 265 mode = SHOWJOBS_PGIDS; 266 break; 267 case 's': 268 mode = SHOWJOBS_PIDS; 269 break; 270 } 271 } 272 273 if (*argptr == NULL) 274 showjobs(0, mode); 275 else 276 while ((id = *argptr++) != NULL) 277 showjob(getjob(id), mode); 278 279 return (0); 280 } 281 282 static void 283 printjobcmd(struct job *jp) 284 { 285 struct procstat *ps; 286 int i; 287 288 for (ps = jp->ps, i = jp->nprocs ; --i >= 0 ; ps++) { 289 out1str(ps->cmd); 290 if (i > 0) 291 out1str(" | "); 292 } 293 out1c('\n'); 294 } 295 296 static void 297 showjob(struct job *jp, int mode) 298 { 299 char s[64]; 300 char statestr[64]; 301 struct procstat *ps; 302 struct job *j; 303 int col, curr, i, jobno, prev, procno; 304 char c; 305 306 procno = (mode == SHOWJOBS_PGIDS) ? 1 : jp->nprocs; 307 jobno = jp - jobtab + 1; 308 curr = prev = 0; 309 #if JOBS 310 if ((j = getcurjob(NULL)) != NULL) { 311 curr = j - jobtab + 1; 312 if ((j = getcurjob(j)) != NULL) 313 prev = j - jobtab + 1; 314 } 315 #endif 316 ps = jp->ps + jp->nprocs - 1; 317 if (jp->state == 0) { 318 strcpy(statestr, "Running"); 319 #if JOBS 320 } else if (jp->state == JOBSTOPPED) { 321 while (!WIFSTOPPED(ps->status) && ps > jp->ps) 322 ps--; 323 if (WIFSTOPPED(ps->status)) 324 i = WSTOPSIG(ps->status); 325 else 326 i = -1; 327 if (i > 0 && i < sys_nsig && sys_siglist[i]) 328 strcpy(statestr, sys_siglist[i]); 329 else 330 strcpy(statestr, "Suspended"); 331 #endif 332 } else if (WIFEXITED(ps->status)) { 333 if (WEXITSTATUS(ps->status) == 0) 334 strcpy(statestr, "Done"); 335 else 336 fmtstr(statestr, 64, "Done(%d)", 337 WEXITSTATUS(ps->status)); 338 } else { 339 i = WTERMSIG(ps->status); 340 if (i > 0 && i < sys_nsig && sys_siglist[i]) 341 strcpy(statestr, sys_siglist[i]); 342 else 343 fmtstr(statestr, 64, "Signal %d", i); 344 if (WCOREDUMP(ps->status)) 345 strcat(statestr, " (core dumped)"); 346 } 347 348 for (ps = jp->ps ; ; ps++) { /* for each process */ 349 if (mode == SHOWJOBS_PIDS || mode == SHOWJOBS_PGIDS) { 350 out1fmt("%d\n", (int)ps->pid); 351 goto skip; 352 } 353 if (mode != SHOWJOBS_VERBOSE && ps != jp->ps) 354 goto skip; 355 if (jobno == curr && ps == jp->ps) 356 c = '+'; 357 else if (jobno == prev && ps == jp->ps) 358 c = '-'; 359 else 360 c = ' '; 361 if (ps == jp->ps) 362 fmtstr(s, 64, "[%d] %c ", jobno, c); 363 else 364 fmtstr(s, 64, " %c ", c); 365 out1str(s); 366 col = strlen(s); 367 if (mode == SHOWJOBS_VERBOSE) { 368 fmtstr(s, 64, "%d ", (int)ps->pid); 369 out1str(s); 370 col += strlen(s); 371 } 372 if (ps == jp->ps) { 373 out1str(statestr); 374 col += strlen(statestr); 375 } 376 do { 377 out1c(' '); 378 col++; 379 } while (col < 30); 380 if (mode == SHOWJOBS_VERBOSE) { 381 out1str(ps->cmd); 382 out1c('\n'); 383 } else 384 printjobcmd(jp); 385 skip: if (--procno <= 0) 386 break; 387 } 388 } 389 390 /* 391 * Print a list of jobs. If "change" is nonzero, only print jobs whose 392 * statuses have changed since the last call to showjobs. 393 * 394 * If the shell is interrupted in the process of creating a job, the 395 * result may be a job structure containing zero processes. Such structures 396 * will be freed here. 397 */ 398 399 void 400 showjobs(int change, int mode) 401 { 402 int jobno; 403 struct job *jp; 404 405 TRACE(("showjobs(%d) called\n", change)); 406 checkzombies(); 407 for (jobno = 1, jp = jobtab ; jobno <= njobs ; jobno++, jp++) { 408 if (! jp->used) 409 continue; 410 if (jp->nprocs == 0) { 411 freejob(jp); 412 continue; 413 } 414 if (change && ! jp->changed) 415 continue; 416 showjob(jp, mode); 417 jp->changed = 0; 418 /* Hack: discard jobs for which $! has not been referenced 419 * in interactive mode when they terminate. 420 */ 421 if (jp->state == JOBDONE && !jp->remembered && 422 (iflag || jp != bgjob)) { 423 freejob(jp); 424 } 425 } 426 } 427 428 429 /* 430 * Mark a job structure as unused. 431 */ 432 433 static void 434 freejob(struct job *jp) 435 { 436 struct procstat *ps; 437 int i; 438 439 INTOFF; 440 if (bgjob == jp) 441 bgjob = NULL; 442 for (i = jp->nprocs, ps = jp->ps ; --i >= 0 ; ps++) { 443 if (ps->cmd != nullstr) 444 ckfree(ps->cmd); 445 } 446 if (jp->ps != &jp->ps0) 447 ckfree(jp->ps); 448 jp->used = 0; 449 #if JOBS 450 deljob(jp); 451 #endif 452 INTON; 453 } 454 455 456 457 int 458 waitcmd(int argc, char **argv) 459 { 460 struct job *job; 461 int status, retval; 462 struct job *jp; 463 464 if (argc > 1) { 465 job = getjob(argv[1]); 466 } else { 467 job = NULL; 468 } 469 470 /* 471 * Loop until a process is terminated or stopped, or a SIGINT is 472 * received. 473 */ 474 475 in_waitcmd++; 476 do { 477 if (job != NULL) { 478 if (job->state) { 479 status = job->ps[job->nprocs - 1].status; 480 if (WIFEXITED(status)) 481 retval = WEXITSTATUS(status); 482 #if JOBS 483 else if (WIFSTOPPED(status)) 484 retval = WSTOPSIG(status) + 128; 485 #endif 486 else 487 retval = WTERMSIG(status) + 128; 488 if (! iflag || ! job->changed) 489 freejob(job); 490 else { 491 job->remembered = 0; 492 if (job == bgjob) 493 bgjob = NULL; 494 } 495 in_waitcmd--; 496 return retval; 497 } 498 } else { 499 for (jp = jobtab ; jp < jobtab + njobs; jp++) 500 if (jp->used && jp->state == JOBDONE) { 501 if (! iflag || ! jp->changed) 502 freejob(jp); 503 else { 504 jp->remembered = 0; 505 if (jp == bgjob) 506 bgjob = NULL; 507 } 508 } 509 for (jp = jobtab ; ; jp++) { 510 if (jp >= jobtab + njobs) { /* no running procs */ 511 in_waitcmd--; 512 return 0; 513 } 514 if (jp->used && jp->state == 0) 515 break; 516 } 517 } 518 } while (dowait(DOWAIT_BLOCK | DOWAIT_SIG, (struct job *)NULL) != -1); 519 in_waitcmd--; 520 521 return 0; 522 } 523 524 525 526 int 527 jobidcmd(int argc __unused, char **argv) 528 { 529 struct job *jp; 530 int i; 531 532 jp = getjob(argv[1]); 533 for (i = 0 ; i < jp->nprocs ; ) { 534 out1fmt("%d", (int)jp->ps[i].pid); 535 out1c(++i < jp->nprocs? ' ' : '\n'); 536 } 537 return 0; 538 } 539 540 541 542 /* 543 * Convert a job name to a job structure. 544 */ 545 546 static struct job * 547 getjob(char *name) 548 { 549 int jobno; 550 struct job *found, *jp; 551 pid_t pid; 552 int i; 553 554 if (name == NULL) { 555 #if JOBS 556 currentjob: if ((jp = getcurjob(NULL)) == NULL) 557 error("No current job"); 558 return (jp); 559 #else 560 error("No current job"); 561 #endif 562 } else if (name[0] == '%') { 563 if (is_digit(name[1])) { 564 jobno = number(name + 1); 565 if (jobno > 0 && jobno <= njobs 566 && jobtab[jobno - 1].used != 0) 567 return &jobtab[jobno - 1]; 568 #if JOBS 569 } else if (name[1] == '%' && name[2] == '\0') { 570 goto currentjob; 571 } else if (name[1] == '+' && name[2] == '\0') { 572 goto currentjob; 573 } else if (name[1] == '-' && name[2] == '\0') { 574 if ((jp = getcurjob(NULL)) == NULL || 575 (jp = getcurjob(jp)) == NULL) 576 error("No previous job"); 577 return (jp); 578 #endif 579 } else if (name[1] == '?') { 580 found = NULL; 581 for (jp = jobtab, i = njobs ; --i >= 0 ; jp++) { 582 if (jp->used && jp->nprocs > 0 583 && strstr(jp->ps[0].cmd, name + 2) != NULL) { 584 if (found) 585 error("%s: ambiguous", name); 586 found = jp; 587 } 588 } 589 if (found != NULL) 590 return (found); 591 } else { 592 found = NULL; 593 for (jp = jobtab, i = njobs ; --i >= 0 ; jp++) { 594 if (jp->used && jp->nprocs > 0 595 && prefix(name + 1, jp->ps[0].cmd)) { 596 if (found) 597 error("%s: ambiguous", name); 598 found = jp; 599 } 600 } 601 if (found) 602 return found; 603 } 604 } else if (is_number(name)) { 605 pid = (pid_t)number(name); 606 for (jp = jobtab, i = njobs ; --i >= 0 ; jp++) { 607 if (jp->used && jp->nprocs > 0 608 && jp->ps[jp->nprocs - 1].pid == pid) 609 return jp; 610 } 611 } 612 error("No such job: %s", name); 613 /*NOTREACHED*/ 614 return NULL; 615 } 616 617 618 pid_t 619 getjobpgrp(char *name) 620 { 621 struct job *jp; 622 623 jp = getjob(name); 624 return -jp->ps[0].pid; 625 } 626 627 /* 628 * Return a new job structure, 629 */ 630 631 struct job * 632 makejob(union node *node __unused, int nprocs) 633 { 634 int i; 635 struct job *jp; 636 637 for (i = njobs, jp = jobtab ; ; jp++) { 638 if (--i < 0) { 639 INTOFF; 640 if (njobs == 0) { 641 jobtab = ckmalloc(4 * sizeof jobtab[0]); 642 #if JOBS 643 jobmru = NULL; 644 #endif 645 } else { 646 jp = ckmalloc((njobs + 4) * sizeof jobtab[0]); 647 memcpy(jp, jobtab, njobs * sizeof jp[0]); 648 #if JOBS 649 /* Relocate `next' pointers and list head */ 650 if (jobmru != NULL) 651 jobmru = &jp[jobmru - jobtab]; 652 for (i = 0; i < njobs; i++) 653 if (jp[i].next != NULL) 654 jp[i].next = &jp[jp[i].next - 655 jobtab]; 656 #endif 657 if (bgjob != NULL) 658 bgjob = &jp[bgjob - jobtab]; 659 /* Relocate `ps' pointers */ 660 for (i = 0; i < njobs; i++) 661 if (jp[i].ps == &jobtab[i].ps0) 662 jp[i].ps = &jp[i].ps0; 663 ckfree(jobtab); 664 jobtab = jp; 665 } 666 jp = jobtab + njobs; 667 for (i = 4 ; --i >= 0 ; jobtab[njobs++].used = 0); 668 INTON; 669 break; 670 } 671 if (jp->used == 0) 672 break; 673 } 674 INTOFF; 675 jp->state = 0; 676 jp->used = 1; 677 jp->changed = 0; 678 jp->nprocs = 0; 679 jp->foreground = 0; 680 jp->remembered = 0; 681 #if JOBS 682 jp->jobctl = jobctl; 683 jp->next = NULL; 684 #endif 685 if (nprocs > 1) { 686 jp->ps = ckmalloc(nprocs * sizeof (struct procstat)); 687 } else { 688 jp->ps = &jp->ps0; 689 } 690 INTON; 691 TRACE(("makejob(%p, %d) returns %%%td\n", (void *)node, nprocs, 692 jp - jobtab + 1)); 693 return jp; 694 } 695 696 #if JOBS 697 static void 698 setcurjob(struct job *cj) 699 { 700 struct job *jp, *prev; 701 702 for (prev = NULL, jp = jobmru; jp != NULL; prev = jp, jp = jp->next) { 703 if (jp == cj) { 704 if (prev != NULL) 705 prev->next = jp->next; 706 else 707 jobmru = jp->next; 708 jp->next = jobmru; 709 jobmru = cj; 710 return; 711 } 712 } 713 cj->next = jobmru; 714 jobmru = cj; 715 } 716 717 static void 718 deljob(struct job *j) 719 { 720 struct job *jp, *prev; 721 722 for (prev = NULL, jp = jobmru; jp != NULL; prev = jp, jp = jp->next) { 723 if (jp == j) { 724 if (prev != NULL) 725 prev->next = jp->next; 726 else 727 jobmru = jp->next; 728 return; 729 } 730 } 731 } 732 733 /* 734 * Return the most recently used job that isn't `nj', and preferably one 735 * that is stopped. 736 */ 737 static struct job * 738 getcurjob(struct job *nj) 739 { 740 struct job *jp; 741 742 /* Try to find a stopped one.. */ 743 for (jp = jobmru; jp != NULL; jp = jp->next) 744 if (jp->used && jp != nj && jp->state == JOBSTOPPED) 745 return (jp); 746 /* Otherwise the most recently used job that isn't `nj' */ 747 for (jp = jobmru; jp != NULL; jp = jp->next) 748 if (jp->used && jp != nj) 749 return (jp); 750 751 return (NULL); 752 } 753 754 #endif 755 756 /* 757 * Fork of a subshell. If we are doing job control, give the subshell its 758 * own process group. Jp is a job structure that the job is to be added to. 759 * N is the command that will be evaluated by the child. Both jp and n may 760 * be NULL. The mode parameter can be one of the following: 761 * FORK_FG - Fork off a foreground process. 762 * FORK_BG - Fork off a background process. 763 * FORK_NOJOB - Like FORK_FG, but don't give the process its own 764 * process group even if job control is on. 765 * 766 * When job control is turned off, background processes have their standard 767 * input redirected to /dev/null (except for the second and later processes 768 * in a pipeline). 769 */ 770 771 pid_t 772 forkshell(struct job *jp, union node *n, int mode) 773 { 774 pid_t pid; 775 pid_t pgrp; 776 777 TRACE(("forkshell(%%%td, %p, %d) called\n", jp - jobtab, (void *)n, 778 mode)); 779 INTOFF; 780 if (mode == FORK_BG && (jp == NULL || jp->nprocs == 0)) 781 checkzombies(); 782 flushall(); 783 pid = fork(); 784 if (pid == -1) { 785 TRACE(("Fork failed, errno=%d\n", errno)); 786 INTON; 787 error("Cannot fork: %s", strerror(errno)); 788 } 789 if (pid == 0) { 790 struct job *p; 791 int wasroot; 792 int i; 793 794 TRACE(("Child shell %d\n", (int)getpid())); 795 wasroot = rootshell; 796 rootshell = 0; 797 handler = &main_handler; 798 closescript(); 799 INTON; 800 forcelocal = 0; 801 clear_traps(); 802 #if JOBS 803 jobctl = 0; /* do job control only in root shell */ 804 if (wasroot && mode != FORK_NOJOB && mflag) { 805 if (jp == NULL || jp->nprocs == 0) 806 pgrp = getpid(); 807 else 808 pgrp = jp->ps[0].pid; 809 if (setpgid(0, pgrp) == 0 && mode == FORK_FG) { 810 /*** this causes superfluous TIOCSPGRPS ***/ 811 if (tcsetpgrp(ttyfd, pgrp) < 0) 812 error("tcsetpgrp failed, errno=%d", errno); 813 } 814 setsignal(SIGTSTP); 815 setsignal(SIGTTOU); 816 } else if (mode == FORK_BG) { 817 ignoresig(SIGINT); 818 ignoresig(SIGQUIT); 819 if ((jp == NULL || jp->nprocs == 0) && 820 ! fd0_redirected_p ()) { 821 close(0); 822 if (open(_PATH_DEVNULL, O_RDONLY) != 0) 823 error("cannot open %s: %s", 824 _PATH_DEVNULL, strerror(errno)); 825 } 826 } 827 #else 828 if (mode == FORK_BG) { 829 ignoresig(SIGINT); 830 ignoresig(SIGQUIT); 831 if ((jp == NULL || jp->nprocs == 0) && 832 ! fd0_redirected_p ()) { 833 close(0); 834 if (open(_PATH_DEVNULL, O_RDONLY) != 0) 835 error("cannot open %s: %s", 836 _PATH_DEVNULL, strerror(errno)); 837 } 838 } 839 #endif 840 INTOFF; 841 for (i = njobs, p = jobtab ; --i >= 0 ; p++) 842 if (p->used) 843 freejob(p); 844 INTON; 845 if (wasroot && iflag) { 846 setsignal(SIGINT); 847 setsignal(SIGQUIT); 848 setsignal(SIGTERM); 849 } 850 return pid; 851 } 852 if (rootshell && mode != FORK_NOJOB && mflag) { 853 if (jp == NULL || jp->nprocs == 0) 854 pgrp = pid; 855 else 856 pgrp = jp->ps[0].pid; 857 setpgid(pid, pgrp); 858 } 859 if (mode == FORK_BG) { 860 if (bgjob != NULL && bgjob->state == JOBDONE && 861 !bgjob->remembered && !iflag) 862 freejob(bgjob); 863 backgndpid = pid; /* set $! */ 864 bgjob = jp; 865 } 866 if (jp) { 867 struct procstat *ps = &jp->ps[jp->nprocs++]; 868 ps->pid = pid; 869 ps->status = -1; 870 ps->cmd = nullstr; 871 if (iflag && rootshell && n) 872 ps->cmd = commandtext(n); 873 jp->foreground = mode == FORK_FG; 874 #if JOBS 875 setcurjob(jp); 876 #endif 877 } 878 INTON; 879 TRACE(("In parent shell: child = %d\n", (int)pid)); 880 return pid; 881 } 882 883 884 pid_t 885 vforkexecshell(struct job *jp, char **argv, char **envp, const char *path, int idx, int pip[2]) 886 { 887 pid_t pid; 888 struct jmploc jmploc; 889 struct jmploc *savehandler; 890 891 TRACE(("vforkexecshell(%%%td, %s, %p) called\n", jp - jobtab, argv[0], 892 (void *)pip)); 893 INTOFF; 894 flushall(); 895 savehandler = handler; 896 pid = vfork(); 897 if (pid == -1) { 898 TRACE(("Vfork failed, errno=%d\n", errno)); 899 INTON; 900 error("Cannot fork: %s", strerror(errno)); 901 } 902 if (pid == 0) { 903 TRACE(("Child shell %d\n", (int)getpid())); 904 if (setjmp(jmploc.loc)) 905 _exit(exception == EXEXEC ? exerrno : 2); 906 if (pip != NULL) { 907 close(pip[0]); 908 if (pip[1] != 1) { 909 dup2(pip[1], 1); 910 close(pip[1]); 911 } 912 } 913 handler = &jmploc; 914 shellexec(argv, envp, path, idx); 915 } 916 handler = savehandler; 917 if (jp) { 918 struct procstat *ps = &jp->ps[jp->nprocs++]; 919 ps->pid = pid; 920 ps->status = -1; 921 ps->cmd = nullstr; 922 jp->foreground = 1; 923 #if JOBS 924 setcurjob(jp); 925 #endif 926 } 927 INTON; 928 TRACE(("In parent shell: child = %d\n", (int)pid)); 929 return pid; 930 } 931 932 933 /* 934 * Wait for job to finish. 935 * 936 * Under job control we have the problem that while a child process is 937 * running interrupts generated by the user are sent to the child but not 938 * to the shell. This means that an infinite loop started by an inter- 939 * active user may be hard to kill. With job control turned off, an 940 * interactive user may place an interactive program inside a loop. If 941 * the interactive program catches interrupts, the user doesn't want 942 * these interrupts to also abort the loop. The approach we take here 943 * is to have the shell ignore interrupt signals while waiting for a 944 * foreground process to terminate, and then send itself an interrupt 945 * signal if the child process was terminated by an interrupt signal. 946 * Unfortunately, some programs want to do a bit of cleanup and then 947 * exit on interrupt; unless these processes terminate themselves by 948 * sending a signal to themselves (instead of calling exit) they will 949 * confuse this approach. 950 */ 951 952 int 953 waitforjob(struct job *jp, int *origstatus) 954 { 955 #if JOBS 956 pid_t mypgrp = getpgrp(); 957 int propagate_int = jp->jobctl && jp->foreground; 958 #endif 959 int status; 960 int st; 961 962 INTOFF; 963 TRACE(("waitforjob(%%%td) called\n", jp - jobtab + 1)); 964 while (jp->state == 0) 965 if (dowait(DOWAIT_BLOCK | (Tflag ? DOWAIT_SIG : 0), jp) == -1) 966 dotrap(); 967 #if JOBS 968 if (jp->jobctl) { 969 if (tcsetpgrp(ttyfd, mypgrp) < 0) 970 error("tcsetpgrp failed, errno=%d\n", errno); 971 } 972 if (jp->state == JOBSTOPPED) 973 setcurjob(jp); 974 #endif 975 status = jp->ps[jp->nprocs - 1].status; 976 if (origstatus != NULL) 977 *origstatus = status; 978 /* convert to 8 bits */ 979 if (WIFEXITED(status)) 980 st = WEXITSTATUS(status); 981 #if JOBS 982 else if (WIFSTOPPED(status)) 983 st = WSTOPSIG(status) + 128; 984 #endif 985 else 986 st = WTERMSIG(status) + 128; 987 if (! JOBS || jp->state == JOBDONE) 988 freejob(jp); 989 if (int_pending()) { 990 if (!WIFSIGNALED(status) || WTERMSIG(status) != SIGINT) 991 CLEAR_PENDING_INT; 992 } 993 #if JOBS 994 else if (rootshell && iflag && propagate_int && 995 WIFSIGNALED(status) && WTERMSIG(status) == SIGINT) 996 kill(getpid(), SIGINT); 997 #endif 998 INTON; 999 return st; 1000 } 1001 1002 1003 static void 1004 dummy_handler(int sig) 1005 { 1006 } 1007 1008 /* 1009 * Wait for a process to terminate. 1010 */ 1011 1012 static pid_t 1013 dowait(int mode, struct job *job) 1014 { 1015 struct sigaction sa, osa; 1016 sigset_t mask, omask; 1017 pid_t pid; 1018 int status; 1019 struct procstat *sp; 1020 struct job *jp; 1021 struct job *thisjob; 1022 int done; 1023 int stopped; 1024 int sig; 1025 int coredump; 1026 int wflags; 1027 int restore_sigchld; 1028 1029 TRACE(("dowait(%d) called\n", block)); 1030 restore_sigchld = 0; 1031 if ((mode & DOWAIT_SIG) != 0) { 1032 sigfillset(&mask); 1033 sigprocmask(SIG_BLOCK, &mask, &omask); 1034 INTOFF; 1035 if (!issigchldtrapped()) { 1036 restore_sigchld = 1; 1037 sa.sa_handler = dummy_handler; 1038 sa.sa_flags = 0; 1039 sigemptyset(&sa.sa_mask); 1040 sigaction(SIGCHLD, &sa, &osa); 1041 } 1042 } 1043 do { 1044 #if JOBS 1045 if (iflag) 1046 wflags = WUNTRACED | WCONTINUED; 1047 else 1048 #endif 1049 wflags = 0; 1050 if ((mode & (DOWAIT_BLOCK | DOWAIT_SIG)) != DOWAIT_BLOCK) 1051 wflags |= WNOHANG; 1052 pid = wait3(&status, wflags, (struct rusage *)NULL); 1053 TRACE(("wait returns %d, status=%d\n", (int)pid, status)); 1054 if (pid == 0 && (mode & DOWAIT_SIG) != 0) { 1055 sigsuspend(&omask); 1056 pid = -1; 1057 if (int_pending()) 1058 break; 1059 } 1060 } while (pid == -1 && errno == EINTR && breakwaitcmd == 0); 1061 if (pid == -1 && errno == ECHILD && job != NULL) 1062 job->state = JOBDONE; 1063 if ((mode & DOWAIT_SIG) != 0) { 1064 if (restore_sigchld) 1065 sigaction(SIGCHLD, &osa, NULL); 1066 sigprocmask(SIG_SETMASK, &omask, NULL); 1067 INTON; 1068 } 1069 if (breakwaitcmd != 0) { 1070 breakwaitcmd = 0; 1071 if (pid <= 0) 1072 return -1; 1073 } 1074 if (pid <= 0) 1075 return pid; 1076 INTOFF; 1077 thisjob = NULL; 1078 for (jp = jobtab ; jp < jobtab + njobs ; jp++) { 1079 if (jp->used && jp->nprocs > 0) { 1080 done = 1; 1081 stopped = 1; 1082 for (sp = jp->ps ; sp < jp->ps + jp->nprocs ; sp++) { 1083 if (sp->pid == -1) 1084 continue; 1085 if (sp->pid == pid) { 1086 TRACE(("Changing status of proc %d from 0x%x to 0x%x\n", 1087 (int)pid, sp->status, 1088 status)); 1089 if (WIFCONTINUED(status)) { 1090 sp->status = -1; 1091 jp->state = 0; 1092 } else 1093 sp->status = status; 1094 thisjob = jp; 1095 } 1096 if (sp->status == -1) 1097 stopped = 0; 1098 else if (WIFSTOPPED(sp->status)) 1099 done = 0; 1100 } 1101 if (stopped) { /* stopped or done */ 1102 int state = done? JOBDONE : JOBSTOPPED; 1103 if (jp->state != state) { 1104 TRACE(("Job %td: changing state from %d to %d\n", jp - jobtab + 1, jp->state, state)); 1105 jp->state = state; 1106 if (jp != job) { 1107 if (done && !jp->remembered && 1108 !iflag && jp != bgjob) 1109 freejob(jp); 1110 #if JOBS 1111 else if (done) 1112 deljob(jp); 1113 #endif 1114 } 1115 } 1116 } 1117 } 1118 } 1119 INTON; 1120 if (!thisjob || thisjob->state == 0) 1121 ; 1122 else if ((!rootshell || !iflag || thisjob == job) && 1123 thisjob->foreground && thisjob->state != JOBSTOPPED) { 1124 sig = 0; 1125 coredump = 0; 1126 for (sp = thisjob->ps; sp < thisjob->ps + thisjob->nprocs; sp++) 1127 if (WIFSIGNALED(sp->status)) { 1128 sig = WTERMSIG(sp->status); 1129 coredump = WCOREDUMP(sp->status); 1130 } 1131 if (sig > 0 && sig != SIGINT && sig != SIGPIPE) { 1132 if (sig < sys_nsig && sys_siglist[sig]) 1133 out2str(sys_siglist[sig]); 1134 else 1135 outfmt(out2, "Signal %d", sig); 1136 if (coredump) 1137 out2str(" (core dumped)"); 1138 out2c('\n'); 1139 flushout(out2); 1140 } 1141 } else { 1142 TRACE(("Not printing status, rootshell=%d, job=%p\n", rootshell, job)); 1143 thisjob->changed = 1; 1144 } 1145 return pid; 1146 } 1147 1148 1149 1150 /* 1151 * return 1 if there are stopped jobs, otherwise 0 1152 */ 1153 int job_warning = 0; 1154 int 1155 stoppedjobs(void) 1156 { 1157 int jobno; 1158 struct job *jp; 1159 1160 if (job_warning) 1161 return (0); 1162 for (jobno = 1, jp = jobtab; jobno <= njobs; jobno++, jp++) { 1163 if (jp->used == 0) 1164 continue; 1165 if (jp->state == JOBSTOPPED) { 1166 out2fmt_flush("You have stopped jobs.\n"); 1167 job_warning = 2; 1168 return (1); 1169 } 1170 } 1171 1172 return (0); 1173 } 1174 1175 1176 static void 1177 checkzombies(void) 1178 { 1179 while (njobs > 0 && dowait(0, NULL) > 0) 1180 ; 1181 } 1182 1183 1184 int 1185 backgndpidset(void) 1186 { 1187 return backgndpid != -1; 1188 } 1189 1190 1191 pid_t 1192 backgndpidval(void) 1193 { 1194 if (bgjob != NULL && !forcelocal) 1195 bgjob->remembered = 1; 1196 return backgndpid; 1197 } 1198 1199 /* 1200 * Return a string identifying a command (to be printed by the 1201 * jobs command. 1202 */ 1203 1204 static char *cmdnextc; 1205 static int cmdnleft; 1206 #define MAXCMDTEXT 200 1207 1208 char * 1209 commandtext(union node *n) 1210 { 1211 char *name; 1212 1213 cmdnextc = name = ckmalloc(MAXCMDTEXT); 1214 cmdnleft = MAXCMDTEXT - 4; 1215 cmdtxt(n); 1216 *cmdnextc = '\0'; 1217 return name; 1218 } 1219 1220 1221 static void 1222 cmdtxt(union node *n) 1223 { 1224 union node *np; 1225 struct nodelist *lp; 1226 const char *p; 1227 int i; 1228 char s[2]; 1229 1230 if (n == NULL) 1231 return; 1232 switch (n->type) { 1233 case NSEMI: 1234 cmdtxt(n->nbinary.ch1); 1235 cmdputs("; "); 1236 cmdtxt(n->nbinary.ch2); 1237 break; 1238 case NAND: 1239 cmdtxt(n->nbinary.ch1); 1240 cmdputs(" && "); 1241 cmdtxt(n->nbinary.ch2); 1242 break; 1243 case NOR: 1244 cmdtxt(n->nbinary.ch1); 1245 cmdputs(" || "); 1246 cmdtxt(n->nbinary.ch2); 1247 break; 1248 case NPIPE: 1249 for (lp = n->npipe.cmdlist ; lp ; lp = lp->next) { 1250 cmdtxt(lp->n); 1251 if (lp->next) 1252 cmdputs(" | "); 1253 } 1254 break; 1255 case NSUBSHELL: 1256 cmdputs("("); 1257 cmdtxt(n->nredir.n); 1258 cmdputs(")"); 1259 break; 1260 case NREDIR: 1261 case NBACKGND: 1262 cmdtxt(n->nredir.n); 1263 break; 1264 case NIF: 1265 cmdputs("if "); 1266 cmdtxt(n->nif.test); 1267 cmdputs("; then "); 1268 cmdtxt(n->nif.ifpart); 1269 cmdputs("..."); 1270 break; 1271 case NWHILE: 1272 cmdputs("while "); 1273 goto until; 1274 case NUNTIL: 1275 cmdputs("until "); 1276 until: 1277 cmdtxt(n->nbinary.ch1); 1278 cmdputs("; do "); 1279 cmdtxt(n->nbinary.ch2); 1280 cmdputs("; done"); 1281 break; 1282 case NFOR: 1283 cmdputs("for "); 1284 cmdputs(n->nfor.var); 1285 cmdputs(" in ..."); 1286 break; 1287 case NCASE: 1288 cmdputs("case "); 1289 cmdputs(n->ncase.expr->narg.text); 1290 cmdputs(" in ..."); 1291 break; 1292 case NDEFUN: 1293 cmdputs(n->narg.text); 1294 cmdputs("() ..."); 1295 break; 1296 case NCMD: 1297 for (np = n->ncmd.args ; np ; np = np->narg.next) { 1298 cmdtxt(np); 1299 if (np->narg.next) 1300 cmdputs(" "); 1301 } 1302 for (np = n->ncmd.redirect ; np ; np = np->nfile.next) { 1303 cmdputs(" "); 1304 cmdtxt(np); 1305 } 1306 break; 1307 case NARG: 1308 cmdputs(n->narg.text); 1309 break; 1310 case NTO: 1311 p = ">"; i = 1; goto redir; 1312 case NAPPEND: 1313 p = ">>"; i = 1; goto redir; 1314 case NTOFD: 1315 p = ">&"; i = 1; goto redir; 1316 case NCLOBBER: 1317 p = ">|"; i = 1; goto redir; 1318 case NFROM: 1319 p = "<"; i = 0; goto redir; 1320 case NFROMTO: 1321 p = "<>"; i = 0; goto redir; 1322 case NFROMFD: 1323 p = "<&"; i = 0; goto redir; 1324 redir: 1325 if (n->nfile.fd != i) { 1326 s[0] = n->nfile.fd + '0'; 1327 s[1] = '\0'; 1328 cmdputs(s); 1329 } 1330 cmdputs(p); 1331 if (n->type == NTOFD || n->type == NFROMFD) { 1332 if (n->ndup.dupfd >= 0) 1333 s[0] = n->ndup.dupfd + '0'; 1334 else 1335 s[0] = '-'; 1336 s[1] = '\0'; 1337 cmdputs(s); 1338 } else { 1339 cmdtxt(n->nfile.fname); 1340 } 1341 break; 1342 case NHERE: 1343 case NXHERE: 1344 cmdputs("<<..."); 1345 break; 1346 default: 1347 cmdputs("???"); 1348 break; 1349 } 1350 } 1351 1352 1353 1354 static void 1355 cmdputs(const char *s) 1356 { 1357 const char *p; 1358 char *q; 1359 char c; 1360 int subtype = 0; 1361 1362 if (cmdnleft <= 0) 1363 return; 1364 p = s; 1365 q = cmdnextc; 1366 while ((c = *p++) != '\0') { 1367 if (c == CTLESC) 1368 *q++ = *p++; 1369 else if (c == CTLVAR) { 1370 *q++ = '$'; 1371 if (--cmdnleft > 0) 1372 *q++ = '{'; 1373 subtype = *p++; 1374 if ((subtype & VSTYPE) == VSLENGTH && --cmdnleft > 0) 1375 *q++ = '#'; 1376 } else if (c == '=' && subtype != 0) { 1377 *q = "}-+?=##%%\0X"[(subtype & VSTYPE) - VSNORMAL]; 1378 if (*q) 1379 q++; 1380 else 1381 cmdnleft++; 1382 if (((subtype & VSTYPE) == VSTRIMLEFTMAX || 1383 (subtype & VSTYPE) == VSTRIMRIGHTMAX) && 1384 --cmdnleft > 0) 1385 *q = q[-1], q++; 1386 subtype = 0; 1387 } else if (c == CTLENDVAR) { 1388 *q++ = '}'; 1389 } else if (c == CTLBACKQ || c == CTLBACKQ+CTLQUOTE) { 1390 cmdnleft -= 5; 1391 if (cmdnleft > 0) { 1392 *q++ = '$'; 1393 *q++ = '('; 1394 *q++ = '.'; 1395 *q++ = '.'; 1396 *q++ = '.'; 1397 *q++ = ')'; 1398 } 1399 } else if (c == CTLARI) { 1400 cmdnleft -= 2; 1401 if (cmdnleft > 0) { 1402 *q++ = '$'; 1403 *q++ = '('; 1404 *q++ = '('; 1405 } 1406 p++; 1407 } else if (c == CTLENDARI) { 1408 if (--cmdnleft > 0) { 1409 *q++ = ')'; 1410 *q++ = ')'; 1411 } 1412 } else if (c == CTLQUOTEMARK || c == CTLQUOTEEND) 1413 cmdnleft++; /* ignore */ 1414 else 1415 *q++ = c; 1416 if (--cmdnleft <= 0) { 1417 *q++ = '.'; 1418 *q++ = '.'; 1419 *q++ = '.'; 1420 break; 1421 } 1422 } 1423 cmdnextc = q; 1424 } 1425