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