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