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