1 /* $NetBSD: jobs.c,v 1.124 2025/04/09 12:04:19 kre 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.124 2025/04/09 12:04:19 kre Exp $"); 41 #endif 42 #endif /* not lint */ 43 44 #include <stdio.h> 45 #include <fcntl.h> 46 #include <signal.h> 47 #include <errno.h> 48 #include <unistd.h> 49 #include <stdlib.h> 50 #include <paths.h> 51 #include <sys/types.h> 52 #include <sys/param.h> 53 #ifdef BSD 54 #include <sys/wait.h> 55 #include <sys/time.h> 56 #include <sys/resource.h> 57 #endif 58 #include <sys/ioctl.h> 59 60 #include "shell.h" 61 #if JOBS 62 #if OLD_TTY_DRIVER 63 #include "sgtty.h" 64 #else 65 #include <termios.h> 66 #endif 67 #undef CEOF /* syntax.h redefines this */ 68 #endif 69 #include "redir.h" 70 #include "show.h" 71 #include "main.h" 72 #include "parser.h" 73 #include "nodes.h" 74 #include "jobs.h" 75 #include "var.h" 76 #include "options.h" 77 #include "builtins.h" 78 #include "trap.h" 79 #include "syntax.h" 80 #include "input.h" 81 #include "output.h" 82 #include "memalloc.h" 83 #include "error.h" 84 #include "mystring.h" 85 86 87 #ifndef WCONTINUED 88 #define WCONTINUED 0 /* So we can compile on old systems */ 89 #endif 90 #ifndef WIFCONTINUED 91 #define WIFCONTINUED(x) (0) /* ditto */ 92 #endif 93 94 95 static struct job *jobtab; /* array of jobs */ 96 static int njobs; /* size of array */ 97 static int jobs_invalid; /* set in child */ 98 MKINIT pid_t backgndpid = -1; /* pid of last background process */ 99 #if JOBS 100 int initialpgrp; /* pgrp of shell on invocation */ 101 static int curjob = -1; /* current job */ 102 #endif 103 static int ttyfd = -1; 104 105 STATIC void restartjob(struct job *); 106 STATIC void freejob(struct job *); 107 STATIC struct job *getjob(const char *, int); 108 STATIC int dowait(int, struct job *, struct job **); 109 #define WBLOCK 1 110 #define WNOFREE 2 111 #define WSILENT 4 112 STATIC int jobstatus(const struct job *, int); 113 STATIC int waitproc(int, struct job *, int *); 114 STATIC int cmdtxt(union node *, int); 115 STATIC void cmdlist(union node *, int); 116 STATIC void cmdputs(const char *); 117 inline static void cmdputi(int); 118 119 #define JNUM(j) ((int)((j) != NULL ? ((j) - jobtab) + 1 : 0)) 120 121 #ifdef SYSV 122 STATIC int onsigchild(void); 123 #endif 124 125 #ifdef OLD_TTY_DRIVER 126 static pid_t tcgetpgrp(int fd); 127 static int tcsetpgrp(int fd, pid_t pgrp); 128 129 static pid_t 130 tcgetpgrp(int fd) 131 { 132 pid_t pgrp; 133 if (ioctl(fd, TIOCGPGRP, (char *)&pgrp) == -1) 134 return -1; 135 else 136 return pgrp; 137 } 138 139 static int 140 tcsetpgrp(int fd, pid_tpgrp) 141 { 142 return ioctl(fd, TIOCSPGRP, (char *)&pgrp); 143 } 144 #endif 145 146 static void 147 ttyfd_change(int from, int to) 148 { 149 if (ttyfd == from) 150 ttyfd = to; 151 } 152 153 /* 154 * Turn job control on and off. 155 * 156 * Note: This code assumes that the third arg to ioctl is a character 157 * pointer, which is true on Berkeley systems but not System V. Since 158 * System V doesn't have job control yet, this isn't a problem now. 159 */ 160 161 MKINIT int jobctl; 162 163 void 164 setjobctl(int on) 165 { 166 #ifdef OLD_TTY_DRIVER 167 int ldisc; 168 #endif 169 170 if (on == jobctl || rootshell == 0) 171 return; 172 if (on) { 173 #if defined(FIOCLEX) || defined(FD_CLOEXEC) 174 int i; 175 176 if (ttyfd != -1) 177 sh_close(ttyfd); 178 if ((ttyfd = open("/dev/tty", O_RDWR)) == -1) { 179 for (i = 0; i < 3; i++) { 180 if (isatty(i) && (ttyfd = dup(i)) != -1) 181 break; 182 } 183 if (i == 3) 184 goto out; 185 } 186 ttyfd = to_upper_fd(ttyfd); /* Move to a high fd */ 187 register_sh_fd(ttyfd, ttyfd_change); 188 #else 189 out2str("sh: Need FIOCLEX or FD_CLOEXEC to support job control"); 190 goto out; 191 #endif 192 if ((initialpgrp = tcgetpgrp(ttyfd)) < 0) { 193 out: 194 out2str("sh: can't access tty; job control turned off\n"); 195 mflag = 0; 196 return; 197 } 198 if (initialpgrp == -1) 199 initialpgrp = getpgrp(); 200 else if (initialpgrp != getpgrp()) 201 killpg(0, SIGTTIN); 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 sh_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 if (jobs_invalid) 260 error("No current jobs"); 261 jp = getjob(arg_ptr, 0); 262 if (jp->jobctl == 0) 263 error("job not created under job control"); 264 out1fmt("%s", jp->ps[0].cmd); 265 for (i = 1; i < jp->nprocs; i++) 266 out1fmt(" | %s", jp->ps[i].cmd ); 267 out1c('\n'); 268 flushall(); 269 270 if (tcsetpgrp(ttyfd, jp->pgrp) == -1) { 271 error("Cannot set tty process group (%s) at %d", 272 strerror(errno), __LINE__); 273 } 274 INTOFF; 275 restartjob(jp); 276 status = waitforjob(jp); 277 INTON; 278 return status; 279 } 280 281 int 282 fgcmd(int argc, char **argv) 283 { 284 nextopt(""); 285 return do_fgcmd(*argptr); 286 } 287 288 int 289 fgcmd_percent(int argc, char **argv) 290 { 291 nextopt(""); 292 return do_fgcmd(*argv); 293 } 294 295 static void 296 set_curjob(struct job *jp, int mode) 297 { 298 struct job *jp1, *jp2; 299 int i, ji; 300 301 ji = jp - jobtab; 302 303 /* first remove from list */ 304 if (ji == curjob) 305 curjob = jp->prev_job; 306 else { 307 for (i = 0; i < njobs; i++) { 308 if (jobtab[i].prev_job != ji) 309 continue; 310 jobtab[i].prev_job = jp->prev_job; 311 break; 312 } 313 } 314 315 /* Then re-insert in correct position */ 316 switch (mode) { 317 case 0: /* job being deleted */ 318 jp->prev_job = -1; 319 break; 320 case 1: /* newly created job or backgrounded job, 321 put after all stopped jobs. */ 322 if (curjob != -1 && jobtab[curjob].state == JOBSTOPPED) { 323 for (jp1 = jobtab + curjob; ; jp1 = jp2) { 324 if (jp1->prev_job == -1) 325 break; 326 jp2 = jobtab + jp1->prev_job; 327 if (jp2->state != JOBSTOPPED) 328 break; 329 } 330 jp->prev_job = jp1->prev_job; 331 jp1->prev_job = ji; 332 break; 333 } 334 /* FALLTHROUGH */ 335 case 2: /* newly stopped job - becomes curjob */ 336 jp->prev_job = curjob; 337 curjob = ji; 338 break; 339 } 340 } 341 342 int 343 bgcmd(int argc, char **argv) 344 { 345 struct job *jp; 346 int i; 347 348 nextopt(""); 349 if (jobs_invalid) 350 error("No current jobs"); 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("[%d] %s", JNUM(jp), 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, e; 372 373 if (jp->state == JOBDONE) 374 return; 375 if (jp->pgrp == 0) 376 error("Job [%d] does not have a process group", JNUM(jp)); 377 378 INTOFF; 379 for (e = i = 0; i < jp->nprocs; i++) { 380 /* 381 * Don't touch a process we already waited for and collected 382 * exit status, that pid may have been reused for something 383 * else - even another of our jobs 384 */ 385 if (jp->ps[i].status != -1 && !WIFSTOPPED(jp->ps[i].status)) 386 continue; 387 388 /* 389 * Otherwise tell it to continue, if it worked, we're done 390 * (we signal the whole process group) 391 */ 392 if (killpg(jp->pgrp, SIGCONT) != -1) 393 break; 394 e = errno; 395 break; /* no point trying again */ 396 } 397 398 if (e != 0) 399 error("Cannot continue job (%s)", strerror(e)); 400 else if (i >= jp->nprocs) 401 error("Job [%d] has no stopped processes", JNUM(jp)); 402 403 /* 404 * Now change state of all stopped processes in the job to running 405 * If there were any, the job is now running as well. 406 */ 407 for (ps = jp->ps, i = jp->nprocs ; --i >= 0 ; ps++) { 408 if (WIFSTOPPED(ps->status)) { 409 VTRACE(DBG_JOBS, ( 410 "restartjob: [%d] pid %d status change" 411 " from %#x (stopped) to -1 (running)\n", 412 JNUM(jp), ps->pid, ps->status)); 413 ps->status = -1; 414 jp->state = JOBRUNNING; 415 } 416 } 417 INTON; 418 } 419 #endif 420 421 inline static void 422 cmdputi(int n) 423 { 424 char str[20]; 425 426 fmtstr(str, sizeof str, "%d", n); 427 cmdputs(str); 428 } 429 430 static void 431 showjob(struct output *out, struct job *jp, int mode) 432 { 433 int procno; 434 int st; 435 struct procstat *ps; 436 int col; 437 char s[64]; 438 439 #if JOBS 440 if (mode & SHOW_PGID) { 441 /* output only the process group ID (lead process ID) */ 442 outfmt(out, "%ld\n", 443 jp->pgrp != 0 ? (long)jp->pgrp : (long)jp->ps->pid); 444 return; 445 } 446 #endif 447 448 procno = jp->nprocs; 449 if (!procno) 450 return; 451 452 if (mode & SHOW_PID) 453 mode |= SHOW_MULTILINE; 454 455 if ((procno > 1 && !(mode & SHOW_MULTILINE)) 456 || (mode & SHOW_SIGNALLED)) { 457 /* See if we have more than one status to report */ 458 ps = jp->ps; 459 st = ps->status; 460 do { 461 int st1 = ps->status; 462 if (st1 != st) 463 /* yes - need multi-line output */ 464 mode |= SHOW_MULTILINE; 465 if (st1 == -1 || !(mode & SHOW_SIGNALLED) || WIFEXITED(st1)) 466 continue; 467 if (WIFSTOPPED(st1) || ((st1 = WTERMSIG(st1) & 0x7f) 468 && st1 != SIGINT && st1 != SIGPIPE)) 469 mode |= SHOW_ISSIG; 470 471 } while (ps++, --procno); 472 procno = jp->nprocs; 473 } 474 475 if (mode & SHOW_SIGNALLED && !(mode & SHOW_ISSIG)) { 476 if (jp->state == JOBDONE && !(mode & SHOW_NO_FREE)) { 477 VTRACE(DBG_JOBS, ("showjob: freeing job %d\n", 478 JNUM(jp))); 479 freejob(jp); 480 } 481 return; 482 } 483 484 for (ps = jp->ps; --procno >= 0; ps++) { /* for each process */ 485 if (ps == jp->ps) 486 fmtstr(s, 16, "[%d] %c ", 487 JNUM(jp), 488 #if JOBS 489 jp - jobtab == curjob ? 490 '+' : 491 curjob != -1 && 492 jp - jobtab == jobtab[curjob].prev_job ? 493 '-' : 494 #endif 495 ' '); 496 else 497 fmtstr(s, 16, " " ); 498 col = strlen(s); 499 if (mode & SHOW_PID) { 500 fmtstr(s + col, 16, "%ld ", (long)ps->pid); 501 col += strlen(s + col); 502 } 503 if (ps->status == -1) { 504 scopy("Running", s + col); 505 } else if (WIFEXITED(ps->status)) { 506 st = WEXITSTATUS(ps->status); 507 if (st) 508 fmtstr(s + col, 16, "Done(%d)", st); 509 else 510 fmtstr(s + col, 16, "Done"); 511 } else { 512 #if JOBS 513 if (WIFSTOPPED(ps->status)) 514 st = WSTOPSIG(ps->status); 515 else /* WIFSIGNALED(ps->status) */ 516 #endif 517 st = WTERMSIG(ps->status); 518 scopyn(strsignal(st), s + col, 32); 519 if (WCOREDUMP(ps->status)) { 520 col += strlen(s + col); 521 scopyn(" (core dumped)", s + col, 64 - col); 522 } 523 } 524 col += strlen(s + col); 525 outstr(s, out); 526 do { 527 outc(' ', out); 528 col++; 529 } while (col < 30); 530 outstr(ps->cmd, out); 531 if (mode & SHOW_MULTILINE) { 532 if (procno > 0) { 533 outc(' ', out); 534 outc('|', out); 535 } 536 } else { 537 while (--procno >= 0) 538 outfmt(out, " | %s", (++ps)->cmd ); 539 } 540 outc('\n', out); 541 } 542 flushout(out); 543 jp->flags &= ~JOBCHANGED; 544 if (jp->state == JOBDONE && !(mode & SHOW_NO_FREE)) 545 freejob(jp); 546 } 547 548 int 549 jobscmd(int argc, char **argv) 550 { 551 int mode, m; 552 553 mode = 0; 554 while ((m = nextopt("lpZ"))) 555 switch (m) { 556 case 'l': 557 mode = SHOW_PID; 558 break; 559 case 'p': 560 mode = SHOW_PGID; 561 break; 562 case 'Z': 563 mode = SHOW_PROCTITLE; 564 break; 565 } 566 567 if (mode == SHOW_PROCTITLE) { 568 if (*argptr && **argptr) 569 setproctitle("%s", *argptr); 570 else 571 setproctitle(NULL); 572 return 0; 573 } 574 575 if (!iflag && !posix) 576 mode |= SHOW_NO_FREE; 577 578 if (*argptr) { 579 do 580 showjob(out1, getjob(*argptr,0), mode); 581 while (*++argptr); 582 } else 583 showjobs(out1, mode); 584 return 0; 585 } 586 587 588 /* 589 * Print a list of jobs. If "change" is nonzero, only print jobs whose 590 * statuses have changed since the last call to showjobs. 591 * 592 * If the shell is interrupted in the process of creating a job, the 593 * result may be a job structure containing zero processes. Such structures 594 * will be freed here. 595 */ 596 597 void 598 showjobs(struct output *out, int mode) 599 { 600 int jobno; 601 struct job *jp; 602 int silent = 0, gotpid; 603 604 CTRACE(DBG_JOBS, ("showjobs(%x) called\n", mode)); 605 606 /* Collect everything pending in the kernel */ 607 if ((gotpid = dowait(WSILENT, NULL, NULL)) > 0) 608 while (dowait(WSILENT, NULL, NULL) > 0) 609 continue; 610 #ifdef JOBS 611 /* 612 * Check if we are not in our foreground group, and if not 613 * put us in it. 614 */ 615 if (mflag && gotpid != -1 && tcgetpgrp(ttyfd) != getpid()) { 616 if (tcsetpgrp(ttyfd, getpid()) == -1) 617 error("Cannot set tty process group (%s) at %d", 618 strerror(errno), __LINE__); 619 VTRACE(DBG_JOBS|DBG_INPUT, ("repaired tty process group\n")); 620 silent = 1; 621 } 622 #endif 623 624 for (jobno = 1, jp = jobtab ; jobno <= njobs ; jobno++, jp++) { 625 if (!jp->used) 626 continue; 627 if (jp->nprocs == 0) { 628 if (!jobs_invalid) 629 freejob(jp); 630 continue; 631 } 632 if ((mode & SHOW_CHANGED) && !(jp->flags & JOBCHANGED)) 633 continue; 634 if (silent && (jp->flags & JOBCHANGED)) { 635 jp->flags &= ~JOBCHANGED; 636 continue; 637 } 638 showjob(out, jp, mode); 639 } 640 } 641 642 /* 643 * Mark a job structure as unused. 644 */ 645 646 STATIC void 647 freejob(struct job *jp) 648 { 649 INTOFF; 650 if (jp->ps != &jp->ps0) { 651 ckfree(jp->ps); 652 jp->ps = &jp->ps0; 653 } 654 jp->nprocs = 0; 655 jp->used = 0; 656 #if JOBS 657 set_curjob(jp, 0); 658 #endif 659 INTON; 660 } 661 662 /* 663 * Extract the status of a completed job (for $?) 664 */ 665 STATIC int 666 jobstatus(const struct job *jp, int raw) 667 { 668 int status = 0; 669 int retval; 670 671 if ((jp->flags & JPIPEFAIL) && jp->nprocs) { 672 int i; 673 674 for (i = 0; i < jp->nprocs; i++) 675 if (jp->ps[i].status != 0) 676 status = jp->ps[i].status; 677 } else 678 status = jp->ps[jp->nprocs ? jp->nprocs - 1 : 0].status; 679 680 if (raw) 681 return status; 682 683 if (WIFEXITED(status)) 684 retval = WEXITSTATUS(status); 685 #if JOBS 686 else if (WIFSTOPPED(status)) 687 retval = WSTOPSIG(status) + 128; 688 #endif 689 else { 690 /* XXX: limits number of signals */ 691 retval = WTERMSIG(status) + 128; 692 } 693 694 return retval; 695 } 696 697 698 699 int 700 waitcmd(int argc, char **argv) 701 { 702 struct job *job, *last; 703 int retval; 704 struct job *jp; 705 int i; 706 int any = 0; 707 int found; 708 int oldwait = 0; 709 char *pid = NULL, *fpid; 710 char **arg; 711 char idstring[20]; 712 713 while ((i = nextopt("np:")) != '\0') { 714 switch (i) { 715 case 'n': 716 any = 1; 717 break; 718 case 'p': 719 if (pid) 720 error("more than one -p unsupported"); 721 pid = optionarg; 722 break; 723 } 724 } 725 726 if (!any && *argptr == 0) 727 oldwait = 1; 728 729 if (pid != NULL) { 730 if (!validname(pid, '\0', NULL)) 731 error("invalid name: -p '%s'", pid); 732 if (unsetvar(pid, 0)) 733 error("%s readonly", pid); 734 } 735 736 /* 737 * If we have forked, and not yet created any new jobs, then 738 * we have no children, whatever jobtab claims, 739 * so simply return in that case. 740 * 741 * The return code is 127 if we had any pid args (none are found) 742 * or if we had -n (nothing exited), but 0 for plain old "wait". 743 */ 744 if (jobs_invalid) { 745 CTRACE(DBG_WAIT, ("builtin wait%s%s in child, invalid jobtab\n", 746 any ? " -n" : "", *argptr ? " pid..." : "")); 747 return oldwait ? 0 : 127; 748 } 749 750 /* 751 * clear stray flags left from previous waitcmd 752 * or set them instead if anything will do ("wait -n") 753 */ 754 for (jp = jobtab, i = njobs ; --i >= 0 ; jp++) { 755 if (any && *argptr == NULL) 756 jp->flags |= JOBWANTED; 757 else 758 jp->flags &= ~JOBWANTED; 759 jp->ref = NULL; 760 } 761 762 CTRACE(DBG_WAIT, 763 ("builtin wait%s%s\n", any ? " -n" : "", *argptr ? " pid..." : "")); 764 765 /* 766 * First, validate the jobnum args, count how many refer to 767 * (different) running jobs, and if we had -n, and found that one has 768 * already finished, we return that one. Otherwise remember 769 * which ones we are looking for (JOBWANTED). 770 */ 771 found = 0; 772 last = NULL; 773 #ifdef DEBUG 774 job = NULL; 775 #endif 776 for (arg = argptr; *arg; arg++) { 777 last = jp = getjob(*arg, 1); 778 if (!jp) 779 continue; 780 if (jp->ref == NULL) 781 jp->ref = *arg; 782 if (any && jp->state == JOBDONE) { 783 /* 784 * We just want any of them, and this one is 785 * ready for consumption, bon apetit ... 786 */ 787 retval = jobstatus(jp, 0); 788 if (pid) 789 setvar(pid, *arg, 0); 790 if (!iflag) 791 freejob(jp); 792 CTRACE(DBG_WAIT, ("wait -n found %s already done: %d\n", *arg, retval)); 793 return retval; 794 } 795 if (!(jp->flags & JOBWANTED)) { 796 /* 797 * It is possible to list the same job several 798 * times - the obvious "wait 1 1 1" or 799 * "wait %% %2 102" where job 2 is current and pid 102 800 * However many times it is requested, it is found once. 801 */ 802 found++; 803 jp->flags |= JOBWANTED; 804 } 805 #ifdef DEBUG 806 job = jp; 807 #endif 808 } 809 810 VTRACE(DBG_WAIT, ("wait %s%s%sfound %d candidates (last %s)\n", 811 any ? "-n " : "", *argptr ? *argptr : "", 812 argptr[0] && argptr[1] ? "... " : " ", found, 813 job && job->used ? (job->ref ? job->ref : "<no-arg>") : "none")); 814 815 /* 816 * If we were given a list of jobnums: 817 * and none of those exist, then we're done. 818 */ 819 if (*argptr && found == 0) 820 return 127; 821 822 /* 823 * Otherwise we need to wait for something to complete 824 * When it does, we check and see if it is one of the 825 * jobs we're waiting on, and if so, we clean it up. 826 * If we had -n, then we're done, otherwise we do it all again 827 * until all we had listed are done, of if there were no 828 * jobnum args, all are done. 829 */ 830 831 retval = any || *argptr ? 127 : 0; 832 fpid = NULL; 833 for (;;) { 834 VTRACE(DBG_WAIT, ("wait waiting (%d remain): ", found)); 835 job = NULL; 836 for (jp = jobtab, i = njobs; --i >= 0; jp++) { 837 if (jp->used && jp->flags & JOBWANTED && 838 jp->state == JOBDONE) { 839 job = jp; 840 break; 841 } 842 if (jp->used && jp->state == JOBRUNNING) 843 job = jp; 844 } 845 if (i < 0 && job == NULL) { 846 CTRACE(DBG_WAIT, ("nothing running (ret: %d) fpid %s\n", 847 retval, fpid ? fpid : "unset")); 848 if (pid && fpid) 849 setvar(pid, fpid, 0); 850 return retval; 851 } 852 jp = job; 853 VTRACE(DBG_WAIT, ("found @%d/%d state: %d\n", njobs-i, njobs, 854 jp->state)); 855 856 /* 857 * There is at least 1 job running, so we can 858 * safely wait() (blocking) for something to exit. 859 */ 860 if (jp->state == JOBRUNNING) { 861 job = NULL; 862 if ((i = dowait(WBLOCK|WNOFREE, NULL, &job)) == -1) 863 return 128 + lastsig(); 864 865 /* 866 * This happens if an interloper has died 867 * (eg: a child of the executable that exec'd us) 868 * Simply go back and start all over again 869 * (this is rare). 870 */ 871 if (job == NULL) 872 continue; 873 874 /* 875 * one of the reported job's processes exited, 876 * but there are more still running, back for more 877 */ 878 if (job->state == JOBRUNNING) 879 continue; 880 } else 881 job = jp; /* we want this, and it is done */ 882 883 if (job->flags & JOBWANTED) { 884 int rv; 885 886 job->flags &= ~JOBWANTED; /* got it */ 887 rv = jobstatus(job, 0); 888 VTRACE(DBG_WAIT, ( 889 "wanted %d (%s) done: st=%d", i, 890 job->ref ? job->ref : "", rv)); 891 if (any || job == last) { 892 retval = rv; 893 fpid = job->ref; 894 895 VTRACE(DBG_WAIT, (" save")); 896 if (pid) { 897 /* 898 * don't need fpid unless we are going 899 * to return it. 900 */ 901 if (fpid == NULL) { 902 /* 903 * this only happens with "wait -n" 904 * (that is, no pid args) 905 */ 906 snprintf(idstring, sizeof idstring, 907 "%d", job->ps[ job->nprocs ? 908 job->nprocs-1 : 0 ].pid); 909 fpid = idstring; 910 } 911 VTRACE(DBG_WAIT, (" (for %s)", fpid)); 912 } 913 } 914 915 if (job->state == JOBDONE) { 916 VTRACE(DBG_WAIT, (" free")); 917 freejob(job); 918 } 919 920 if (any || (found > 0 && --found == 0)) { 921 if (pid && fpid) 922 setvar(pid, fpid, 0); 923 VTRACE(DBG_WAIT, (" return %d\n", retval)); 924 return retval; 925 } 926 VTRACE(DBG_WAIT, ("\n")); 927 continue; 928 } 929 930 /* this is to handle "wait" (no args) */ 931 if (oldwait && job->state == JOBDONE) { 932 VTRACE(DBG_JOBS|DBG_WAIT, ("Cleanup: %d\n", i)); 933 freejob(job); 934 } 935 } 936 } 937 938 939 int 940 jobidcmd(int argc, char **argv) 941 { 942 struct job *jp; 943 int i; 944 int pg = 0, onep = 0, job = 0; 945 946 while ((i = nextopt("gjp"))) { 947 switch (i) { 948 case 'g': pg = 1; break; 949 case 'j': job = 1; break; 950 case 'p': onep = 1; break; 951 } 952 } 953 CTRACE(DBG_JOBS, ("jobidcmd%s%s%s%s %s\n", pg ? " -g" : "", 954 onep ? " -p" : "", job ? " -j" : "", jobs_invalid ? " [inv]" : "", 955 *argptr ? *argptr : "<implicit %%>")); 956 if (pg + onep + job > 1) 957 error("-g -j and -p options cannot be combined"); 958 959 if (argptr[0] && argptr[1]) 960 error("usage: jobid [-g|-p|-r] jobid"); 961 962 jp = getjob(*argptr, 0); 963 if (job) { 964 out1fmt("%%%d\n", JNUM(jp)); 965 return 0; 966 } 967 if (pg) { 968 if (jp->pgrp != 0) { 969 out1fmt("%ld\n", (long)jp->pgrp); 970 return 0; 971 } 972 return 1; 973 } 974 if (onep) { 975 i = jp->nprocs - 1; 976 if (i < 0) 977 return 1; 978 out1fmt("%ld\n", (long)jp->ps[i].pid); 979 return 0; 980 } 981 for (i = 0 ; i < jp->nprocs ; ) { 982 out1fmt("%ld", (long)jp->ps[i].pid); 983 out1c(++i < jp->nprocs ? ' ' : '\n'); 984 } 985 return 0; 986 } 987 988 #if JOBS 989 #ifndef SMALL 990 991 static int 992 stop_me(int sig, int force, int pgrp, pid_t pid) 993 { 994 if (force || (!loginsh && mflag && rootshell)) { 995 struct sigaction sig_dfl, sig_was; 996 997 sig_dfl.sa_handler = SIG_DFL; 998 sig_dfl.sa_flags = 0; 999 sigemptyset(&sig_dfl.sa_mask); 1000 1001 (void)sigaction(sig, &sig_dfl, &sig_was); 1002 1003 if (kill(pgrp ? 0 : pid, sig) == -1) { 1004 sh_warn("suspend myself"); 1005 (void)sigaction(sig, &sig_was, NULL); 1006 error(NULL); 1007 } 1008 1009 (void)sigaction(sig, &sig_was, NULL); 1010 1011 return 0; 1012 } 1013 1014 if (!rootshell) 1015 sh_warnx("subshell environment"); 1016 else if (!mflag) 1017 sh_warnx("job control disabled"); 1018 else if (loginsh) 1019 sh_warnx("login shell"); 1020 else 1021 sh_warnx("not possible??"); 1022 1023 return 1; 1024 } 1025 1026 int 1027 suspendcmd(int argc, char **argv) 1028 { 1029 int sig = SIGTSTP; 1030 int force = 0; 1031 int pgrp = 0; 1032 int status = 0; 1033 char *target; 1034 int c; 1035 1036 while ((c = nextopt("fgs:")) != 0) { 1037 switch (c) { 1038 case 'f': 1039 force = 1; 1040 break; 1041 case 'g': 1042 pgrp = 1; 1043 break; 1044 case 's': 1045 sig = signame_to_signum(optionarg); 1046 1047 if (sig != SIGSTOP && sig != SIGTSTP && 1048 sig != SIGTTIN && sig != SIGTTOU) 1049 error("bad signal '%s'", optionarg); 1050 break; 1051 } 1052 } 1053 1054 if (!*argptr) /* suspend myself */ 1055 return stop_me(sig, force, pgrp, getpid()); 1056 1057 while ((target = *argptr++) != NULL) 1058 { 1059 int pid; 1060 1061 if (is_number(target)) { 1062 if ((pid = number(target)) == 0) { 1063 sh_warnx("Cannot (yet) suspend kernel (%s)", 1064 target); 1065 status = 1; 1066 continue; 1067 } 1068 } else if ((pid = getjobpgrp(target)) == 0) { 1069 sh_warnx("Unknown job: %s", target); 1070 status = 1; 1071 continue; 1072 } 1073 1074 if (pid == rootpid || pid == getpid()) { 1075 status |= stop_me(sig, force, pgrp, pid); 1076 continue; 1077 } 1078 1079 if (pid == 1 || pid == -1) { 1080 sh_warnx("Don't be funny"); 1081 status = 1; 1082 continue; 1083 } 1084 1085 if (pid > 0 && pgrp) 1086 pid = -pid; 1087 1088 if (kill(pid, sig) == -1) { 1089 sh_warn("failed to suspend %s", target); 1090 status = 1; 1091 } 1092 } 1093 1094 return status; 1095 } 1096 #endif /* SMALL */ 1097 #endif /* JOBS */ 1098 1099 int 1100 getjobpgrp(const char *name) 1101 { 1102 struct job *jp; 1103 1104 if (jobs_invalid) 1105 return 0; 1106 jp = getjob(name, 1); 1107 if (jp == 0) 1108 return 0; 1109 return -jp->pgrp; 1110 } 1111 1112 /* 1113 * Convert a job name to a job structure. 1114 */ 1115 1116 STATIC struct job * 1117 getjob(const char *name, int noerror) 1118 { 1119 int jobno = -1; 1120 struct job *jp; 1121 int pid; 1122 int i; 1123 const char *err_msg = "No such job: %s"; 1124 1125 if (name == NULL) { 1126 #if JOBS 1127 jobno = curjob; 1128 #endif 1129 err_msg = "No current job"; 1130 } else if (name[0] == '%') { 1131 if (is_number(name + 1)) { 1132 jobno = number(name + 1) - 1; 1133 } else if (!name[1] || !name[2]) { 1134 switch (name[1]) { 1135 #if JOBS 1136 case 0: 1137 case '+': 1138 case '%': 1139 jobno = curjob; 1140 err_msg = "No current job"; 1141 break; 1142 case '-': 1143 jobno = curjob; 1144 if (jobno != -1) 1145 jobno = jobtab[jobno].prev_job; 1146 err_msg = "No previous job"; 1147 break; 1148 #endif 1149 default: 1150 goto check_pattern; 1151 } 1152 } else { 1153 struct job *found; 1154 check_pattern: 1155 found = NULL; 1156 for (jp = jobtab, i = njobs ; --i >= 0 ; jp++) { 1157 if (!jp->used || jp->nprocs <= 0) 1158 continue; 1159 if ((name[1] == '?' 1160 && strstr(jp->ps[0].cmd, name + 2)) 1161 || prefix(name + 1, jp->ps[0].cmd)) { 1162 if (found) { 1163 err_msg = "%s: ambiguous"; 1164 found = 0; 1165 break; 1166 } 1167 found = jp; 1168 } 1169 } 1170 if (found) 1171 return found; 1172 } 1173 1174 } else if (is_number(name)) { 1175 pid = number(name); 1176 for (jp = jobtab, i = njobs ; --i >= 0 ; jp++) { 1177 if (jp->used && jp->nprocs > 0 1178 && jp->ps[jp->nprocs - 1].pid == pid) 1179 return jp; 1180 } 1181 } 1182 1183 if (jobno >= 0 && jobno < njobs) { 1184 jp = jobtab + jobno; 1185 if (jp->used) 1186 return jp; 1187 } 1188 if (!noerror) 1189 error(err_msg, name); 1190 return 0; 1191 } 1192 1193 1194 /* 1195 * Find out if there are any running (that is, unwaited upon) 1196 * background children of the current shell. 1197 * 1198 * Return 1/0 (yes, no). 1199 * 1200 * Needed as we cannot optimise away sub-shell creation if 1201 * we have such a child, or a "wait" in that sub-shell would 1202 * observe the already existing job. 1203 */ 1204 int 1205 anyjobs(void) 1206 { 1207 struct job *jp; 1208 int i; 1209 1210 if (jobs_invalid) 1211 return 0; 1212 1213 for (i = njobs, jp = jobtab ; --i >= 0 ; jp++) { 1214 if (jp->used) 1215 return 1; 1216 } 1217 1218 return 0; 1219 } 1220 1221 /* 1222 * Output the (new) POSIX required "[%d] %d" string whenever an 1223 * async (ie: background) job is started in an interactive shell. 1224 * Note that a subshell environment is not regarded as interactive. 1225 */ 1226 void 1227 jobstarted(struct job *jp) 1228 { 1229 if (!iflag || !rootshell) 1230 return; 1231 1232 outfmt(out2, "[%d] %ld\n", JNUM(jp), 1233 jp->pgrp != 0 ? (long)jp->pgrp : (long)jp->ps->pid); 1234 } 1235 1236 /* 1237 * Return a new job structure, 1238 */ 1239 1240 struct job * 1241 makejob(union node *node, int nprocs) 1242 { 1243 int i; 1244 struct job *jp; 1245 1246 if (jobs_invalid) { 1247 VTRACE(DBG_JOBS, ("makejob(%p, %d) clearing jobtab (%d)\n", 1248 (void *)node, nprocs, njobs)); 1249 for (i = njobs, jp = jobtab ; --i >= 0 ; jp++) { 1250 if (jp->used) 1251 freejob(jp); 1252 } 1253 jobs_invalid = 0; 1254 } 1255 1256 for (i = njobs, jp = jobtab ; ; jp++) { 1257 if (--i < 0) { 1258 INTOFF; 1259 if (njobs == 0) { 1260 jobtab = ckmalloc(4 * sizeof jobtab[0]); 1261 } else { 1262 jp = ckmalloc((njobs + 4) * sizeof jobtab[0]); 1263 memcpy(jp, jobtab, njobs * sizeof jp[0]); 1264 /* Relocate `ps' pointers */ 1265 for (i = 0; i < njobs; i++) 1266 if (jp[i].ps == &jobtab[i].ps0) 1267 jp[i].ps = &jp[i].ps0; 1268 ckfree(jobtab); 1269 jobtab = jp; 1270 } 1271 jp = jobtab + njobs; 1272 for (i = 4 ; --i >= 0 ; njobs++) { 1273 jobtab[njobs].used = 0; 1274 jobtab[njobs].prev_job = -1; 1275 } 1276 INTON; 1277 break; 1278 } 1279 if (jp->used == 0) 1280 break; 1281 } 1282 INTOFF; 1283 jp->state = JOBRUNNING; 1284 jp->used = 1; 1285 jp->flags = pipefail ? JPIPEFAIL : 0; 1286 jp->nprocs = 0; 1287 jp->pgrp = 0; 1288 #if JOBS 1289 jp->jobctl = jobctl; 1290 set_curjob(jp, 1); 1291 #endif 1292 if (nprocs > 1) { 1293 jp->ps = ckmalloc(nprocs * sizeof (struct procstat)); 1294 } else { 1295 jp->ps = &jp->ps0; 1296 } 1297 INTON; 1298 VTRACE(DBG_JOBS, ("makejob(%p, %d)%s returns %%%d\n", (void *)node, 1299 nprocs, (jp->flags & JPIPEFAIL) ? " PF" : "", JNUM(jp))); 1300 return jp; 1301 } 1302 1303 1304 /* 1305 * Fork off a subshell. If we are doing job control, give the subshell its 1306 * own process group. Jp is a job structure that the job is to be added to. 1307 * N is the command that will be evaluated by the child. Both jp and n may 1308 * be NULL. The mode parameter can be one of the following: 1309 * FORK_FG - Fork off a foreground process. 1310 * FORK_BG - Fork off a background process. 1311 * FORK_NOJOB - Like FORK_FG, but don't give the process its own 1312 * process group even if job control is on. 1313 * 1314 * When job control is turned off, background processes have their standard 1315 * input redirected to /dev/null (except for the second and later processes 1316 * in a pipeline). 1317 */ 1318 1319 int 1320 forkshell(struct job *jp, union node *n, int mode) 1321 { 1322 pid_t pid; 1323 int serrno; 1324 1325 CTRACE(DBG_JOBS, ("forkshell(%%%d, %p, %d) called\n", 1326 JNUM(jp), n, mode)); 1327 1328 switch ((pid = fork())) { 1329 case -1: 1330 serrno = errno; 1331 VTRACE(DBG_JOBS, ("Fork failed, errno=%d\n", serrno)); 1332 error("Cannot fork (%s)", strerror(serrno)); 1333 break; 1334 case 0: 1335 SHELL_FORKED(); 1336 forkchild(jp, n, mode, 0); 1337 return 0; 1338 default: 1339 return forkparent(jp, n, mode, pid); 1340 } 1341 } 1342 1343 int 1344 forkparent(struct job *jp, union node *n, int mode, pid_t pid) 1345 { 1346 int pgrp = 0; 1347 1348 if (rootshell && mode != FORK_NOJOB && mflag) { 1349 /* 1350 * The process group ID must always be that of the 1351 * first process created for the job. If this proc 1352 * is the first, that's us, otherwise the pgrp has 1353 * already been determined. 1354 */ 1355 if (jp == NULL || jp->nprocs == 0) 1356 pgrp = pid; 1357 else 1358 pgrp = jp->pgrp; 1359 /* This can fail because we are doing it in the child also */ 1360 (void)setpgid(pid, pgrp); 1361 } 1362 if (mode == FORK_BG) 1363 backgndpid = pid; /* set $! */ 1364 if (jp) { 1365 struct procstat *ps = &jp->ps[jp->nprocs++]; 1366 ps->pid = pid; 1367 ps->status = -1; 1368 ps->cmd[0] = 0; 1369 jp->pgrp = pgrp; /* 0 if !mflag */ 1370 if (/* iflag && rootshell && */ n) 1371 commandtext(ps, n); 1372 } 1373 CTRACE(DBG_JOBS, ("In parent shell: child = %d (mode %d)\n",pid,mode)); 1374 return pid; 1375 } 1376 1377 void 1378 forkchild(struct job *jp, union node *n, int mode, int vforked) 1379 { 1380 int wasroot; 1381 int pgrp; 1382 const char *devnull = _PATH_DEVNULL; 1383 const char *nullerr = "Can't open %s"; 1384 1385 wasroot = rootshell; 1386 CTRACE(DBG_JOBS, ("Child shell %d %sforked from %d (mode %d)\n", 1387 getpid(), vforked?"v":"", getppid(), mode)); 1388 1389 if (!vforked) { 1390 rootshell = 0; 1391 handler = &main_handler; 1392 } 1393 1394 closescript(vforked); 1395 clear_traps(vforked); 1396 #if JOBS 1397 if (!vforked) 1398 jobctl = 0; /* do job control only in root shell */ 1399 if (wasroot && mode != FORK_NOJOB && mflag) { 1400 if (jp == NULL || jp->nprocs == 0) 1401 pgrp = getpid(); 1402 else 1403 pgrp = jp->ps[0].pid; 1404 /* This can fail because we are doing it in the parent also */ 1405 (void)setpgid(0, pgrp); 1406 if (mode == FORK_FG) { 1407 if (tcsetpgrp(ttyfd, pgrp) == -1) 1408 error("Cannot set tty process group (%s) at %d", 1409 strerror(errno), __LINE__); 1410 } 1411 setsignal(SIGTSTP, vforked); 1412 setsignal(SIGTTOU, vforked); 1413 } else if (mode == FORK_BG) { 1414 ignoresig(SIGINT, vforked); 1415 ignoresig(SIGQUIT, vforked); 1416 if ((jp == NULL || jp->nprocs == 0) && 1417 ! fd0_redirected_p ()) { 1418 close(0); 1419 if (open(devnull, O_RDONLY) != 0) 1420 error(nullerr, devnull); 1421 } 1422 } 1423 #else 1424 if (mode == FORK_BG) { 1425 ignoresig(SIGINT, vforked); 1426 ignoresig(SIGQUIT, vforked); 1427 if ((jp == NULL || jp->nprocs == 0) && 1428 ! fd0_redirected_p ()) { 1429 close(0); 1430 if (open(devnull, O_RDONLY) != 0) 1431 error(nullerr, devnull); 1432 } 1433 } 1434 #endif 1435 if (wasroot && iflag) { 1436 setsignal(SIGINT, vforked); 1437 setsignal(SIGQUIT, vforked); 1438 setsignal(SIGTERM, vforked); 1439 } 1440 1441 if (!vforked) 1442 jobs_invalid = 1; 1443 } 1444 1445 /* 1446 * Wait for job to finish. 1447 * 1448 * Under job control we have the problem that while a child process is 1449 * running interrupts generated by the user are sent to the child but not 1450 * to the shell. This means that an infinite loop started by an inter- 1451 * active user may be hard to kill. With job control turned off, an 1452 * interactive user may place an interactive program inside a loop. If 1453 * the interactive program catches interrupts, the user doesn't want 1454 * these interrupts to also abort the loop. The approach we take here 1455 * is to have the shell ignore interrupt signals while waiting for a 1456 * foreground process to terminate, and then send itself an interrupt 1457 * signal if the child process was terminated by an interrupt signal. 1458 * Unfortunately, some programs want to do a bit of cleanup and then 1459 * exit on interrupt; unless these processes terminate themselves by 1460 * sending a signal to themselves (instead of calling exit) they will 1461 * confuse this approach. 1462 */ 1463 1464 int 1465 waitforjob(struct job *jp) 1466 { 1467 #if JOBS 1468 int mypgrp = getpgrp(); 1469 #endif 1470 int status; 1471 int st; 1472 1473 INTOFF; 1474 VTRACE(DBG_JOBS, ("waitforjob(%%%d) called\n", JNUM(jp))); 1475 while (jp->state == JOBRUNNING) { 1476 dowait(WBLOCK, jp, NULL); 1477 } 1478 #if JOBS 1479 if (jp->jobctl) { 1480 if (tcsetpgrp(ttyfd, mypgrp) == -1) 1481 error("Cannot set tty process group (%s) at %d", 1482 strerror(errno), __LINE__); 1483 } 1484 if (jp->state == JOBSTOPPED && curjob != jp - jobtab) 1485 set_curjob(jp, 2); 1486 #endif 1487 status = jobstatus(jp, 1); 1488 1489 /* convert to 8 bits */ 1490 if (WIFEXITED(status)) 1491 st = WEXITSTATUS(status); 1492 #if JOBS 1493 else if (WIFSTOPPED(status)) 1494 st = WSTOPSIG(status) + 128; 1495 #endif 1496 else 1497 st = WTERMSIG(status) + 128; 1498 1499 VTRACE(DBG_JOBS, ("waitforjob: job %d, nproc %d, status %d, st %x\n", 1500 JNUM(jp), jp->nprocs, status, st)); 1501 #if JOBS 1502 if (jp->jobctl) { 1503 /* 1504 * This is truly gross. 1505 * If we're doing job control, then we did a TIOCSPGRP which 1506 * caused us (the shell) to no longer be in the controlling 1507 * session -- so we wouldn't have seen any ^C/SIGINT. So, we 1508 * intuit from the subprocess exit status whether a SIGINT 1509 * occurred, and if so interrupt ourselves. Yuck. - mycroft 1510 */ 1511 if (WIFSIGNALED(status) && WTERMSIG(status) == SIGINT) 1512 raise(SIGINT); 1513 } 1514 #endif 1515 if (! JOBS || jp->state == JOBDONE) 1516 freejob(jp); 1517 INTON; 1518 return st; 1519 } 1520 1521 1522 1523 /* 1524 * Wait for a process (any process) to terminate. 1525 * 1526 * If "job" is given (not NULL), then its jobcontrol status (and mflag) 1527 * are used to determine if we wait for stopping/continuing processes or 1528 * only terminating ones, and the decision whether to report to stdout 1529 * or not varies depending what happened, and whether the affected job 1530 * is the one that was requested or not. 1531 * 1532 * If "changed" is not NULL, then the job which changed because a 1533 * process terminated/stopped will be reported by setting *changed, 1534 * if there is any such job, otherwise we set *changed = NULL. 1535 */ 1536 1537 STATIC int 1538 dowait(int flags, struct job *job, struct job **changed) 1539 { 1540 int pid; 1541 int status; 1542 struct procstat *sp; 1543 struct job *jp; 1544 struct job *thisjob; 1545 int done; 1546 int stopped; 1547 int err; 1548 1549 VTRACE(DBG_JOBS|DBG_PROCS, ("dowait(%x) called for job %d%s\n", 1550 flags, JNUM(job), changed ? " [report change]" : "")); 1551 1552 if (changed != NULL) 1553 *changed = NULL; 1554 1555 /* 1556 * First deal with the kernel, collect info on any (one) of our 1557 * children that has changed state since we last asked. 1558 * (loop if we're interrupted by a signal that we aren't processing) 1559 */ 1560 do { 1561 err = 0; 1562 pid = waitproc(flags & WBLOCK, job, &status); 1563 if (pid == -1) 1564 err = errno; 1565 VTRACE(DBG_JOBS|DBG_PROCS, 1566 ("wait returns pid %d (e:%d), status %#x (ps=%d)\n", 1567 pid, err, status, pendingsigs)); 1568 } while (pid == -1 && err == EINTR && pendingsigs == 0); 1569 1570 /* 1571 * if nothing exited/stopped/..., we have nothing else to do 1572 */ 1573 if (pid <= 0) 1574 return pid; 1575 1576 /* 1577 * Otherwise, try to find the process, somewhere in our job table 1578 */ 1579 INTOFF; 1580 thisjob = NULL; 1581 for (jp = jobtab ; jp < jobtab + njobs ; jp++) { 1582 if (jp->used) { 1583 /* 1584 * For each job that is in use (this is one) 1585 */ 1586 done = 1; /* assume it is finished */ 1587 stopped = 1; /* and has stopped */ 1588 1589 /* 1590 * Now scan all our child processes of the job 1591 */ 1592 for (sp = jp->ps ; sp < jp->ps + jp->nprocs ; sp++) { 1593 if (sp->pid == -1) 1594 continue; 1595 /* 1596 * If the process that changed is the one 1597 * we're looking at, and it was previously 1598 * running (-1) or was stopped (anything else 1599 * and it must have already finished earlier, 1600 * so cannot be the process that just changed) 1601 * then we update its status 1602 */ 1603 if (sp->pid == pid && 1604 (sp->status==-1 || WIFSTOPPED(sp->status))) { 1605 VTRACE(DBG_JOBS | DBG_PROCS, 1606 ("Job %d: changing status of proc %d from %#x to ", 1607 JNUM(jp), pid, sp->status)); 1608 1609 /* 1610 * If the process continued, 1611 * then update its status to running 1612 * and mark the job running as well. 1613 * 1614 * If it was anything but running 1615 * before, flag it as a change for 1616 * reporting purposes later 1617 */ 1618 if (WIFCONTINUED(status)) { 1619 if (sp->status != -1) 1620 jp->flags |= JOBCHANGED; 1621 sp->status = -1; 1622 jp->state = JOBRUNNING; 1623 VTRACE(DBG_JOBS|DBG_PROCS, 1624 ("running\n")); 1625 } else { 1626 /* otherwise update status */ 1627 sp->status = status; 1628 VTRACE(DBG_JOBS|DBG_PROCS, 1629 ("%#x\n", status)); 1630 } 1631 1632 /* 1633 * We now know the affected job 1634 */ 1635 thisjob = jp; 1636 if (changed != NULL) 1637 *changed = jp; 1638 } 1639 /* 1640 * After any update that might have just 1641 * happened, if this process is running, 1642 * the job is not stopped, or if the process 1643 * simply stopped (not terminated) then the 1644 * job is certainly not completed (done). 1645 */ 1646 if (sp->status == -1) 1647 stopped = 0; 1648 else if (WIFSTOPPED(sp->status)) 1649 done = 0; 1650 } 1651 1652 /* 1653 * Once we have examined all processes for the 1654 * job, if we still show it as stopped, then... 1655 */ 1656 if (stopped) { /* stopped or done */ 1657 /* 1658 * it might be stopped, or finished, decide: 1659 */ 1660 int state = done ? JOBDONE : JOBSTOPPED; 1661 1662 /* 1663 * If that wasn't the same as it was before 1664 * then update its state, and if it just 1665 * completed, make it be the current job (%%) 1666 */ 1667 if (jp->state != state) { 1668 VTRACE(DBG_JOBS, 1669 ("Job %d: changing state from %d to %d\n", 1670 JNUM(jp), jp->state, state)); 1671 jp->state = state; 1672 #if JOBS 1673 if (done) 1674 set_curjob(jp, 0); 1675 #endif 1676 } 1677 } 1678 } 1679 } 1680 1681 /* 1682 * Now we have scanned all jobs. If we found the job that 1683 * the process that changed state belonged to (we occasionally 1684 * fork processes without associating them with a job, when one 1685 * of those finishes, we simply ignore it, the zombie has been 1686 * cleaned up, which is all that matters) then we need to 1687 * determine if we should say something about it to stdout 1688 */ 1689 1690 if (thisjob && 1691 (thisjob->state != JOBRUNNING || thisjob->flags & JOBCHANGED)) { 1692 int mode = 0; 1693 1694 if (!rootshell || !iflag) 1695 mode = SHOW_SIGNALLED; 1696 if ((job == thisjob && (flags & WNOFREE) == 0) || 1697 job != thisjob) 1698 mode = SHOW_SIGNALLED | SHOW_NO_FREE; 1699 if (mode && (flags & WSILENT) == 0) 1700 showjob(out2, thisjob, mode); 1701 else { 1702 VTRACE(DBG_JOBS, 1703 ("Not printing status for %p [%d], " 1704 "mode=%#x rootshell=%d, job=%p [%d]\n", 1705 thisjob, JNUM(thisjob), mode, rootshell, 1706 job, JNUM(job))); 1707 thisjob->flags |= JOBCHANGED; 1708 } 1709 } 1710 1711 INTON; 1712 /* 1713 * Finally tell our caller that something happened (in general all 1714 * anyone tests for is <= 0 (or >0) so the actual pid value here 1715 * doesn't matter much, but we know pid is >0 so we may as well 1716 * give back something meaningful 1717 */ 1718 return pid; 1719 } 1720 1721 1722 1723 /* 1724 * Do a wait system call. If job control is compiled in, we accept 1725 * stopped processes. If block is zero, we return a value of zero 1726 * rather than blocking. 1727 * 1728 * System V doesn't have a non-blocking wait system call. It does 1729 * have a SIGCLD signal that is sent to a process when one of its 1730 * children dies. The obvious way to use SIGCLD would be to install 1731 * a handler for SIGCLD which simply bumped a counter when a SIGCLD 1732 * was received, and have waitproc bump another counter when it got 1733 * the status of a process. Waitproc would then know that a wait 1734 * system call would not block if the two counters were different. 1735 * This approach doesn't work because if a process has children that 1736 * have not been waited for, System V will send it a SIGCLD when it 1737 * installs a signal handler for SIGCLD. What this means is that when 1738 * a child exits, the shell will be sent SIGCLD signals continuously 1739 * until is runs out of stack space, unless it does a wait call before 1740 * restoring the signal handler. The code below takes advantage of 1741 * this (mis)feature by installing a signal handler for SIGCLD and 1742 * then checking to see whether it was called. If there are any 1743 * children to be waited for, it will be. 1744 * 1745 * If neither SYSV nor BSD is defined, we don't implement nonblocking 1746 * waits at all. In this case, the user will not be informed when 1747 * a background process ends until the next time she runs a real program 1748 * (as opposed to running a builtin command or just typing return), 1749 * and the jobs command may give out of date information. 1750 */ 1751 1752 #ifdef SYSV 1753 STATIC int gotsigchild; 1754 1755 STATIC int onsigchild() { 1756 gotsigchild = 1; 1757 } 1758 #endif 1759 1760 1761 STATIC int 1762 waitproc(int block, struct job *jp, int *status) 1763 { 1764 #ifdef BSD 1765 int flags = 0; 1766 1767 #if JOBS 1768 if (mflag || (jp != NULL && jp->jobctl)) 1769 flags |= WUNTRACED | WCONTINUED; 1770 #endif 1771 if (block == 0) 1772 flags |= WNOHANG; 1773 VTRACE(DBG_WAIT, ("waitproc: doing waitpid(flags=%#x)\n", flags)); 1774 return waitpid(-1, status, flags); 1775 #else 1776 #ifdef SYSV 1777 int (*save)(); 1778 1779 if (block == 0) { 1780 gotsigchild = 0; 1781 save = signal(SIGCLD, onsigchild); 1782 signal(SIGCLD, save); 1783 if (gotsigchild == 0) 1784 return 0; 1785 } 1786 return wait(status); 1787 #else 1788 if (block == 0) 1789 return 0; 1790 return wait(status); 1791 #endif 1792 #endif 1793 } 1794 1795 /* 1796 * return 1 if there are stopped jobs, otherwise 0 1797 */ 1798 int job_warning = 0; 1799 int 1800 stoppedjobs(void) 1801 { 1802 int jobno; 1803 struct job *jp; 1804 1805 if (job_warning || jobs_invalid) 1806 return (0); 1807 for (jobno = 1, jp = jobtab; jobno <= njobs; jobno++, jp++) { 1808 if (jp->used == 0) 1809 continue; 1810 if (jp->state == JOBSTOPPED) { 1811 out2str("You have stopped jobs.\n"); 1812 job_warning = 2; 1813 return (1); 1814 } 1815 } 1816 1817 return (0); 1818 } 1819 1820 /* 1821 * Return a string identifying a command (to be printed by the 1822 * jobs command). 1823 */ 1824 1825 STATIC char *cmdnextc; 1826 STATIC int cmdnleft; 1827 1828 void 1829 commandtext(struct procstat *ps, union node *n) 1830 { 1831 int len; 1832 1833 cmdnextc = ps->cmd; 1834 if (iflag || mflag || sizeof(ps->cmd) <= 60) 1835 len = sizeof(ps->cmd); 1836 else if (sizeof ps->cmd <= 400) 1837 len = 50; 1838 else if (sizeof ps->cmd <= 800) 1839 len = 80; 1840 else 1841 len = sizeof(ps->cmd) / 10; 1842 cmdnleft = len; 1843 (void)cmdtxt(n, 1); 1844 if (cmdnleft <= 0) { 1845 char *p = ps->cmd + len - 4; 1846 p[0] = '.'; 1847 p[1] = '.'; 1848 p[2] = '.'; 1849 p[3] = 0; 1850 } else 1851 *cmdnextc = '\0'; 1852 1853 VTRACE(DBG_JOBS, 1854 ("commandtext: ps->cmd %p, end %p, left %d\n\t\"%s\"\n", 1855 ps->cmd, cmdnextc, cmdnleft, ps->cmd)); 1856 } 1857 1858 1859 /* 1860 * Generate a string describing tree node n & its descendants (recursive calls) 1861 * 1862 * Return true (non-zero) if the output is complete (ends with an operator) 1863 * so no ';' need be added before the following command. Return false (zero) 1864 * if a ';' is needed to terminate the output if it is followed by something 1865 * which is not an operator. 1866 */ 1867 STATIC int 1868 cmdtxt(union node *n, int top) 1869 { 1870 union node *np; 1871 struct nodelist *lp; 1872 const char *p; 1873 int i; 1874 1875 if (n == NULL || cmdnleft <= 0) 1876 return 1; 1877 switch (n->type) { 1878 case NSEMI: 1879 if (!cmdtxt(n->nbinary.ch1, 0)) 1880 cmdputs(";"); 1881 cmdputs(" "); 1882 return cmdtxt(n->nbinary.ch2, 0); 1883 case NAND: 1884 (void)cmdtxt(n->nbinary.ch1, 0); 1885 cmdputs(" && "); 1886 return cmdtxt(n->nbinary.ch2, 0); 1887 case NOR: 1888 (void) cmdtxt(n->nbinary.ch1, 0); 1889 cmdputs(" || "); 1890 return cmdtxt(n->nbinary.ch2, 0); 1891 case NDNOT: 1892 cmdputs("! "); 1893 /* FALLTHROUGH */ 1894 case NNOT: 1895 cmdputs("! "); 1896 return cmdtxt(n->nnot.com, 0); 1897 break; 1898 case NPIPE: 1899 for (lp = n->npipe.cmdlist ; lp ; lp = lp->next) { 1900 (void) cmdtxt(lp->n, 0); 1901 if (lp->next) 1902 cmdputs(" | "); 1903 } 1904 if (!top && n->npipe.backgnd) { 1905 cmdputs(" &"); 1906 return 1; 1907 } 1908 return 0; 1909 case NSUBSHELL: 1910 cmdputs("("); 1911 (void) cmdtxt(n->nredir.n, 0); 1912 cmdputs(")"); 1913 return 0; 1914 case NREDIR: 1915 case NBACKGND: 1916 return cmdtxt(n->nredir.n, top); 1917 case NIF: 1918 cmdputs("if "); 1919 if (!cmdtxt(n->nif.test, 0)) 1920 cmdputs(";"); 1921 cmdputs(" then "); 1922 i = cmdtxt(n->nif.ifpart, 0); 1923 if (n->nif.elsepart) { 1924 if (i == 0) 1925 cmdputs(";"); 1926 cmdputs(" else "); 1927 i = cmdtxt(n->nif.elsepart, 0); 1928 } 1929 if (i == 0) 1930 cmdputs(";"); 1931 cmdputs(" fi"); 1932 return 0; 1933 case NWHILE: 1934 cmdputs("while "); 1935 goto until; 1936 case NUNTIL: 1937 cmdputs("until "); 1938 until: 1939 if (!cmdtxt(n->nbinary.ch1, 0)) 1940 cmdputs(";"); 1941 cmdputs(" do "); 1942 if (!cmdtxt(n->nbinary.ch2, 0)) 1943 cmdputs(";"); 1944 cmdputs(" done"); 1945 return 0; 1946 case NFOR: 1947 cmdputs("for "); 1948 cmdputs(n->nfor.var); 1949 cmdputs(" in "); 1950 cmdlist(n->nfor.args, 1); 1951 cmdputs("; do "); 1952 if (!cmdtxt(n->nfor.body, 0)) 1953 cmdputs(";"); 1954 cmdputs(" done"); 1955 return 0; 1956 case NCASE: 1957 cmdputs("case "); 1958 cmdputs(n->ncase.expr->narg.text); 1959 cmdputs(" in "); 1960 for (np = n->ncase.cases; np; np = np->nclist.next) { 1961 (void) cmdtxt(np->nclist.pattern, 0); 1962 cmdputs(") "); 1963 (void) cmdtxt(np->nclist.body, 0); 1964 switch (n->type) { /* switch (not if) for later */ 1965 case NCLISTCONT: 1966 cmdputs(" ;& "); 1967 break; 1968 default: 1969 cmdputs(" ;; "); 1970 break; 1971 } 1972 } 1973 cmdputs("esac"); 1974 return 0; 1975 case NDEFUN: 1976 cmdputs(n->narg.text); 1977 cmdputs("() { ... }"); 1978 return 0; 1979 case NCMD: 1980 cmdlist(n->ncmd.args, 1); 1981 cmdlist(n->ncmd.redirect, 0); 1982 if (!top && n->ncmd.backgnd) { 1983 cmdputs(" &"); 1984 return 1; 1985 } 1986 return 0; 1987 case NARG: 1988 cmdputs(n->narg.text); 1989 return 0; 1990 case NTO: 1991 p = ">"; i = 1; goto redir; 1992 case NCLOBBER: 1993 p = ">|"; i = 1; goto redir; 1994 case NAPPEND: 1995 p = ">>"; i = 1; goto redir; 1996 case NTOFD: 1997 p = ">&"; i = 1; goto redir; 1998 case NFROM: 1999 p = "<"; i = 0; goto redir; 2000 case NFROMFD: 2001 p = "<&"; i = 0; goto redir; 2002 case NFROMTO: 2003 p = "<>"; i = 0; goto redir; 2004 redir: 2005 if (n->nfile.fd != i) 2006 cmdputi(n->nfile.fd); 2007 cmdputs(p); 2008 if (n->type == NTOFD || n->type == NFROMFD) { 2009 if (n->ndup.dupfd < 0) 2010 cmdputs("-"); 2011 else 2012 cmdputi(n->ndup.dupfd); 2013 } else { 2014 (void) cmdtxt(n->nfile.fname, 0); 2015 } 2016 return 0; 2017 case NHERE: 2018 case NXHERE: 2019 cmdputs("<<..."); 2020 return 0; 2021 default: 2022 cmdputs("???"); 2023 return 0; 2024 } 2025 return 0; 2026 } 2027 2028 STATIC void 2029 cmdlist(union node *np, int sep) 2030 { 2031 for (; np; np = np->narg.next) { 2032 if (!sep) 2033 cmdputs(" "); 2034 (void) cmdtxt(np, 0); 2035 if (sep && np->narg.next) 2036 cmdputs(" "); 2037 } 2038 } 2039 2040 2041 STATIC void 2042 cmdputs(const char *s) 2043 { 2044 const char *p, *str = 0; 2045 char c, cc[2] = " "; 2046 char *nextc; 2047 int nleft; 2048 int subtype = 0; 2049 int quoted = 0; 2050 static char vstype[16][4] = { "", "}", "-", "+", "?", "=", 2051 "#", "##", "%", "%%", "}" }; 2052 2053 p = s; 2054 nextc = cmdnextc; 2055 nleft = cmdnleft; 2056 while (nleft > 0 && (c = *p++) != 0) { 2057 switch (c) { 2058 case CTLNONL: 2059 c = '\0'; 2060 break; 2061 case CTLESC: 2062 c = *p++; 2063 break; 2064 case CTLVAR: 2065 subtype = *p++; 2066 if (subtype & VSLINENO) { /* undo LINENO hack */ 2067 if ((subtype & VSTYPE) == VSLENGTH) 2068 str = "${#LINENO"; /*}*/ 2069 else 2070 str = "${LINENO"; /*}*/ 2071 while (is_digit(*p)) 2072 p++; 2073 } else if ((subtype & VSTYPE) == VSLENGTH) 2074 str = "${#"; /*}*/ 2075 else 2076 str = "${"; /*}*/ 2077 if (!(subtype & VSQUOTE) != !(quoted & 1)) { 2078 quoted ^= 1; 2079 c = '"'; 2080 } else { 2081 c = *str++; 2082 } 2083 break; 2084 case CTLENDVAR: /*{*/ 2085 c = '}'; 2086 if (quoted & 1) 2087 str = "\""; 2088 quoted >>= 1; 2089 subtype = 0; 2090 break; 2091 case CTLBACKQ: 2092 c = '$'; 2093 str = "(...)"; 2094 break; 2095 case CTLBACKQ+CTLQUOTE: 2096 c = '"'; 2097 str = "$(...)\""; 2098 break; 2099 case CTLARI: 2100 c = '$'; 2101 if (*p == ' ') 2102 p++; 2103 str = "(("; /*))*/ 2104 break; 2105 case CTLENDARI: /*((*/ 2106 c = ')'; 2107 str = ")"; 2108 break; 2109 case CTLQUOTEMARK: 2110 quoted ^= 1; 2111 c = '"'; 2112 break; 2113 case CTLQUOTEEND: 2114 quoted >>= 1; 2115 c = '"'; 2116 break; 2117 case '=': 2118 if (subtype == 0) 2119 break; 2120 str = vstype[subtype & VSTYPE]; 2121 if (subtype & VSNUL) 2122 c = ':'; 2123 else 2124 c = *str++; /*{*/ 2125 if (c != '}') 2126 quoted <<= 1; 2127 else if (*p == CTLENDVAR) 2128 c = *str++; 2129 subtype = 0; 2130 break; 2131 case '\'': 2132 case '\\': 2133 case '"': 2134 case '$': 2135 /* These can only happen inside quotes */ 2136 cc[0] = c; 2137 str = cc; 2138 c = '\\'; 2139 break; 2140 default: 2141 break; 2142 } 2143 if (c != '\0') do { /* c == 0 implies nothing in str */ 2144 *nextc++ = c; 2145 } while (--nleft > 0 && str && (c = *str++)); 2146 str = 0; 2147 } 2148 if ((quoted & 1) && nleft) { 2149 *nextc++ = '"'; 2150 nleft--; 2151 } 2152 cmdnleft = nleft; 2153 cmdnextc = nextc; 2154 } 2155