1 /* $OpenBSD: jobs.c,v 1.39 2009/12/13 04:36:48 deraadt Exp $ */ 2 3 /*- 4 * Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2011, 5 * 2012, 2013 6 * Thorsten Glaser <tg (at) mirbsd.org> 7 * 8 * Provided that these terms and disclaimer and all copyright notices 9 * are retained or reproduced in an accompanying document, permission 10 * is granted to deal in this work without restriction, including un- 11 * limited rights to use, publicly perform, distribute, sell, modify, 12 * merge, give away, or sublicence. 13 * 14 * This work is provided "AS IS" and WITHOUT WARRANTY of any kind, to 15 * the utmost extent permitted by applicable law, neither express nor 16 * implied; without malicious intent or gross negligence. In no event 17 * may a licensor, author or contributor be held liable for indirect, 18 * direct, other damage, loss, or other issues arising in any way out 19 * of dealing in the work, even if advised of the possibility of such 20 * damage or existence of a defect, except proven that it results out 21 * of said person's immediate fault when using the work as intended. 22 */ 23 24 #include "sh.h" 25 26 __RCSID("$MirOS: src/bin/mksh/jobs.c,v 1.100 2013/07/26 20:33:23 tg Exp $"); 27 28 #if HAVE_KILLPG 29 #define mksh_killpg killpg 30 #else 31 /* cross fingers and hope kill is killpg-endowed */ 32 #define mksh_killpg(p,s) kill(-(p), (s)) 33 #endif 34 35 /* Order important! */ 36 #define PRUNNING 0 37 #define PEXITED 1 38 #define PSIGNALLED 2 39 #define PSTOPPED 3 40 41 typedef struct proc Proc; 42 struct proc { 43 Proc *next; /* next process in pipeline (if any) */ 44 pid_t pid; /* process id */ 45 int state; 46 int status; /* wait status */ 47 /* process command string from vistree */ 48 char command[256 - (ALLOC_SIZE + sizeof(Proc *) + sizeof(pid_t) + 49 2 * sizeof(int))]; 50 }; 51 52 /* Notify/print flag - j_print() argument */ 53 #define JP_SHORT 1 /* print signals processes were killed by */ 54 #define JP_MEDIUM 2 /* print [job-num] -/+ command */ 55 #define JP_LONG 3 /* print [job-num] -/+ pid command */ 56 #define JP_PGRP 4 /* print pgrp */ 57 58 /* put_job() flags */ 59 #define PJ_ON_FRONT 0 /* at very front */ 60 #define PJ_PAST_STOPPED 1 /* just past any stopped jobs */ 61 62 /* Job.flags values */ 63 #define JF_STARTED 0x001 /* set when all processes in job are started */ 64 #define JF_WAITING 0x002 /* set if j_waitj() is waiting on job */ 65 #define JF_W_ASYNCNOTIFY 0x004 /* set if waiting and async notification ok */ 66 #define JF_XXCOM 0x008 /* set for $(command) jobs */ 67 #define JF_FG 0x010 /* running in foreground (also has tty pgrp) */ 68 #define JF_SAVEDTTY 0x020 /* j->ttystat is valid */ 69 #define JF_CHANGED 0x040 /* process has changed state */ 70 #define JF_KNOWN 0x080 /* $! referenced */ 71 #define JF_ZOMBIE 0x100 /* known, unwaited process */ 72 #define JF_REMOVE 0x200 /* flagged for removal (j_jobs()/j_noityf()) */ 73 #define JF_USETTYMODE 0x400 /* tty mode saved if process exits normally */ 74 #define JF_SAVEDTTYPGRP 0x800 /* j->saved_ttypgrp is valid */ 75 76 typedef struct job Job; 77 struct job { 78 Job *next; /* next job in list */ 79 Proc *proc_list; /* process list */ 80 Proc *last_proc; /* last process in list */ 81 struct timeval systime; /* system time used by job */ 82 struct timeval usrtime; /* user time used by job */ 83 pid_t pgrp; /* process group of job */ 84 pid_t ppid; /* pid of process that forked job */ 85 int job; /* job number: %n */ 86 int flags; /* see JF_* */ 87 volatile int state; /* job state */ 88 int status; /* exit status of last process */ 89 int32_t age; /* number of jobs started */ 90 Coproc_id coproc_id; /* 0 or id of coprocess output pipe */ 91 #ifndef MKSH_UNEMPLOYED 92 mksh_ttyst ttystat; /* saved tty state for stopped jobs */ 93 pid_t saved_ttypgrp; /* saved tty process group for stopped jobs */ 94 #endif 95 }; 96 97 /* Flags for j_waitj() */ 98 #define JW_NONE 0x00 99 #define JW_INTERRUPT 0x01 /* ^C will stop the wait */ 100 #define JW_ASYNCNOTIFY 0x02 /* asynchronous notification during wait ok */ 101 #define JW_STOPPEDWAIT 0x04 /* wait even if job stopped */ 102 #define JW_PIPEST 0x08 /* want PIPESTATUS */ 103 104 /* Error codes for j_lookup() */ 105 #define JL_NOSUCH 0 /* no such job */ 106 #define JL_AMBIG 1 /* %foo or %?foo is ambiguous */ 107 #define JL_INVALID 2 /* non-pid, non-% job id */ 108 109 static const char * const lookup_msgs[] = { 110 "no such job", 111 "ambiguous", 112 "argument must be %job or process id" 113 }; 114 115 static Job *job_list; /* job list */ 116 static Job *last_job; 117 static Job *async_job; 118 static pid_t async_pid; 119 120 static int nzombie; /* # of zombies owned by this process */ 121 static int32_t njobs; /* # of jobs started */ 122 123 #ifndef CHILD_MAX 124 #define CHILD_MAX 25 125 #endif 126 127 #ifndef MKSH_NOPROSPECTOFWORK 128 /* held_sigchld is set if sigchld occurs before a job is completely started */ 129 static volatile sig_atomic_t held_sigchld; 130 #endif 131 132 #ifndef MKSH_UNEMPLOYED 133 static struct shf *shl_j; 134 static bool ttypgrp_ok; /* set if can use tty pgrps */ 135 static pid_t restore_ttypgrp = -1; 136 static int const tt_sigs[] = { SIGTSTP, SIGTTIN, SIGTTOU }; 137 #endif 138 139 static void j_set_async(Job *); 140 static void j_startjob(Job *); 141 static int j_waitj(Job *, int, const char *); 142 static void j_sigchld(int); 143 static void j_print(Job *, int, struct shf *); 144 static Job *j_lookup(const char *, int *); 145 static Job *new_job(void); 146 static Proc *new_proc(void); 147 static void check_job(Job *); 148 static void put_job(Job *, int); 149 static void remove_job(Job *, const char *); 150 static int kill_job(Job *, int); 151 152 static void tty_init_talking(void); 153 static void tty_init_state(void); 154 155 /* initialise job control */ 156 void 157 j_init(void) 158 { 159 #ifndef MKSH_UNEMPLOYED 160 bool mflagset = Flag(FMONITOR) != 127; 161 162 Flag(FMONITOR) = 0; 163 #endif 164 165 #ifndef MKSH_NOPROSPECTOFWORK 166 (void)sigemptyset(&sm_default); 167 sigprocmask(SIG_SETMASK, &sm_default, NULL); 168 169 (void)sigemptyset(&sm_sigchld); 170 (void)sigaddset(&sm_sigchld, SIGCHLD); 171 172 setsig(&sigtraps[SIGCHLD], j_sigchld, 173 SS_RESTORE_ORIG|SS_FORCE|SS_SHTRAP); 174 #else 175 /* Make sure SIGCHLD isn't ignored - can do odd things under SYSV */ 176 setsig(&sigtraps[SIGCHLD], SIG_DFL, SS_RESTORE_ORIG|SS_FORCE); 177 #endif 178 179 #ifndef MKSH_UNEMPLOYED 180 if (!mflagset && Flag(FTALKING)) 181 Flag(FMONITOR) = 1; 182 183 /* 184 * shl_j is used to do asynchronous notification (used in 185 * an interrupt handler, so need a distinct shf) 186 */ 187 shl_j = shf_fdopen(2, SHF_WR, NULL); 188 189 if (Flag(FMONITOR) || Flag(FTALKING)) { 190 int i; 191 192 /* 193 * the TF_SHELL_USES test is a kludge that lets us know if 194 * if the signals have been changed by the shell. 195 */ 196 for (i = NELEM(tt_sigs); --i >= 0; ) { 197 sigtraps[tt_sigs[i]].flags |= TF_SHELL_USES; 198 /* j_change() sets this to SS_RESTORE_DFL if FMONITOR */ 199 setsig(&sigtraps[tt_sigs[i]], SIG_IGN, 200 SS_RESTORE_IGN|SS_FORCE); 201 } 202 } 203 204 /* j_change() calls tty_init_talking() and tty_init_state() */ 205 if (Flag(FMONITOR)) 206 j_change(); 207 else 208 #endif 209 if (Flag(FTALKING)) { 210 tty_init_talking(); 211 tty_init_state(); 212 } 213 } 214 215 static int 216 proc_errorlevel(Proc *p) 217 { 218 switch (p->state) { 219 case PEXITED: 220 return (WEXITSTATUS(p->status)); 221 case PSIGNALLED: 222 return (128 + WTERMSIG(p->status)); 223 default: 224 return (0); 225 } 226 } 227 228 /* job cleanup before shell exit */ 229 void 230 j_exit(void) 231 { 232 /* kill stopped, and possibly running, jobs */ 233 Job *j; 234 bool killed = false; 235 236 for (j = job_list; j != NULL; j = j->next) { 237 if (j->ppid == procpid && 238 (j->state == PSTOPPED || 239 (j->state == PRUNNING && 240 ((j->flags & JF_FG) || 241 (Flag(FLOGIN) && !Flag(FNOHUP) && procpid == kshpid))))) { 242 killed = true; 243 if (j->pgrp == 0) 244 kill_job(j, SIGHUP); 245 else 246 mksh_killpg(j->pgrp, SIGHUP); 247 #ifndef MKSH_UNEMPLOYED 248 if (j->state == PSTOPPED) { 249 if (j->pgrp == 0) 250 kill_job(j, SIGCONT); 251 else 252 mksh_killpg(j->pgrp, SIGCONT); 253 } 254 #endif 255 } 256 } 257 if (killed) 258 sleep(1); 259 j_notify(); 260 261 #ifndef MKSH_UNEMPLOYED 262 if (kshpid == procpid && restore_ttypgrp >= 0) { 263 /* 264 * Need to restore the tty pgrp to what it was when the 265 * shell started up, so that the process that started us 266 * will be able to access the tty when we are done. 267 * Also need to restore our process group in case we are 268 * about to do an exec so that both our parent and the 269 * process we are to become will be able to access the tty. 270 */ 271 tcsetpgrp(tty_fd, restore_ttypgrp); 272 setpgid(0, restore_ttypgrp); 273 } 274 if (Flag(FMONITOR)) { 275 Flag(FMONITOR) = 0; 276 j_change(); 277 } 278 #endif 279 } 280 281 #ifndef MKSH_UNEMPLOYED 282 /* turn job control on or off according to Flag(FMONITOR) */ 283 void 284 j_change(void) 285 { 286 int i; 287 288 if (Flag(FMONITOR)) { 289 bool use_tty = Flag(FTALKING); 290 291 /* don't call mksh_tcget until we own the tty process group */ 292 if (use_tty) 293 tty_init_talking(); 294 295 /* no controlling tty, no SIGT* */ 296 if ((ttypgrp_ok = (use_tty && tty_fd >= 0 && tty_devtty))) { 297 setsig(&sigtraps[SIGTTIN], SIG_DFL, 298 SS_RESTORE_ORIG|SS_FORCE); 299 /* wait to be given tty (POSIX.1, B.2, job control) */ 300 while (/* CONSTCOND */ 1) { 301 pid_t ttypgrp; 302 303 if ((ttypgrp = tcgetpgrp(tty_fd)) < 0) { 304 warningf(false, "%s: %s %s: %s", 305 "j_init", "tcgetpgrp", "failed", 306 cstrerror(errno)); 307 ttypgrp_ok = false; 308 break; 309 } 310 if (ttypgrp == kshpgrp) 311 break; 312 kill(0, SIGTTIN); 313 } 314 } 315 for (i = NELEM(tt_sigs); --i >= 0; ) 316 setsig(&sigtraps[tt_sigs[i]], SIG_IGN, 317 SS_RESTORE_DFL|SS_FORCE); 318 if (ttypgrp_ok && kshpgrp != kshpid) { 319 if (setpgid(0, kshpid) < 0) { 320 warningf(false, "%s: %s %s: %s", "j_init", 321 "setpgid", "failed", cstrerror(errno)); 322 ttypgrp_ok = false; 323 } else { 324 if (tcsetpgrp(tty_fd, kshpid) < 0) { 325 warningf(false, "%s: %s %s: %s", 326 "j_init", "tcsetpgrp", "failed", 327 cstrerror(errno)); 328 ttypgrp_ok = false; 329 } else 330 restore_ttypgrp = kshpgrp; 331 kshpgrp = kshpid; 332 } 333 } 334 #ifndef MKSH_DISABLE_TTY_WARNING 335 if (use_tty && !ttypgrp_ok) 336 warningf(false, "%s: %s", "warning", 337 "won't have full job control"); 338 #endif 339 } else { 340 ttypgrp_ok = false; 341 if (Flag(FTALKING)) 342 for (i = NELEM(tt_sigs); --i >= 0; ) 343 setsig(&sigtraps[tt_sigs[i]], SIG_IGN, 344 SS_RESTORE_IGN|SS_FORCE); 345 else 346 for (i = NELEM(tt_sigs); --i >= 0; ) { 347 if (sigtraps[tt_sigs[i]].flags & 348 (TF_ORIG_IGN | TF_ORIG_DFL)) 349 setsig(&sigtraps[tt_sigs[i]], 350 (sigtraps[tt_sigs[i]].flags & TF_ORIG_IGN) ? 351 SIG_IGN : SIG_DFL, 352 SS_RESTORE_ORIG|SS_FORCE); 353 } 354 } 355 tty_init_state(); 356 } 357 #endif 358 359 #if HAVE_NICE 360 /* run nice(3) and ignore the result */ 361 static void 362 ksh_nice(int ness) 363 { 364 #if defined(__USE_FORTIFY_LEVEL) && (__USE_FORTIFY_LEVEL > 0) 365 int eno; 366 367 errno = 0; 368 /* this is gonna annoy users; complain to your distro, people! */ 369 if (nice(ness) == -1 && (eno = errno) != 0) 370 warningf(false, "%s: %s", "bgnice", cstrerror(eno)); 371 #else 372 (void)nice(ness); 373 #endif 374 } 375 #endif 376 377 /* execute tree in child subprocess */ 378 int 379 exchild(struct op *t, int flags, 380 volatile int *xerrok, 381 /* used if XPCLOSE or XCCLOSE */ 382 int close_fd) 383 { 384 /* for pipelines */ 385 static Proc *last_proc; 386 387 int rv = 0, forksleep, jwflags = JW_NONE; 388 #ifndef MKSH_NOPROSPECTOFWORK 389 sigset_t omask; 390 #endif 391 Proc *p; 392 Job *j; 393 pid_t cldpid; 394 395 if (flags & XPIPEST) { 396 flags &= ~XPIPEST; 397 jwflags |= JW_PIPEST; 398 } 399 400 if (flags & XEXEC) 401 /* 402 * Clear XFORK|XPCLOSE|XCCLOSE|XCOPROC|XPIPEO|XPIPEI|XXCOM|XBGND 403 * (also done in another execute() below) 404 */ 405 return (execute(t, flags & (XEXEC | XERROK), xerrok)); 406 407 #ifndef MKSH_NOPROSPECTOFWORK 408 /* no SIGCHLDs while messing with job and process lists */ 409 sigprocmask(SIG_BLOCK, &sm_sigchld, &omask); 410 #endif 411 412 p = new_proc(); 413 p->next = NULL; 414 p->state = PRUNNING; 415 p->status = 0; 416 p->pid = 0; 417 418 /* link process into jobs list */ 419 if (flags & XPIPEI) { 420 /* continuing with a pipe */ 421 if (!last_job) 422 internal_errorf("%s %d", 423 "exchild: XPIPEI and no last_job - pid", 424 (int)procpid); 425 j = last_job; 426 if (last_proc) 427 last_proc->next = p; 428 last_proc = p; 429 } else { 430 /* fills in j->job */ 431 j = new_job(); 432 /* 433 * we don't consider XXCOMs foreground since they don't get 434 * tty process group and we don't save or restore tty modes. 435 */ 436 j->flags = (flags & XXCOM) ? JF_XXCOM : 437 ((flags & XBGND) ? 0 : (JF_FG|JF_USETTYMODE)); 438 timerclear(&j->usrtime); 439 timerclear(&j->systime); 440 j->state = PRUNNING; 441 j->pgrp = 0; 442 j->ppid = procpid; 443 j->age = ++njobs; 444 j->proc_list = p; 445 j->coproc_id = 0; 446 last_job = j; 447 last_proc = p; 448 put_job(j, PJ_PAST_STOPPED); 449 } 450 451 vistree(p->command, sizeof(p->command), t); 452 453 /* create child process */ 454 forksleep = 1; 455 while ((cldpid = fork()) < 0 && errno == EAGAIN && forksleep < 32) { 456 if (intrsig) 457 /* allow user to ^C out... */ 458 break; 459 sleep(forksleep); 460 forksleep <<= 1; 461 } 462 /* ensure $RANDOM changes between parent and child */ 463 rndset((unsigned long)cldpid); 464 /* fork failed? */ 465 if (cldpid < 0) { 466 kill_job(j, SIGKILL); 467 remove_job(j, "fork failed"); 468 #ifndef MKSH_NOPROSPECTOFWORK 469 sigprocmask(SIG_SETMASK, &omask, NULL); 470 #endif 471 errorf("can't fork - try again"); 472 } 473 p->pid = cldpid ? cldpid : (procpid = getpid()); 474 475 #ifndef MKSH_UNEMPLOYED 476 /* job control set up */ 477 if (Flag(FMONITOR) && !(flags&XXCOM)) { 478 bool dotty = false; 479 480 if (j->pgrp == 0) { 481 /* First process */ 482 j->pgrp = p->pid; 483 dotty = true; 484 } 485 486 /* 487 * set pgrp in both parent and child to deal with race 488 * condition 489 */ 490 setpgid(p->pid, j->pgrp); 491 if (ttypgrp_ok && dotty && !(flags & XBGND)) 492 tcsetpgrp(tty_fd, j->pgrp); 493 } 494 #endif 495 496 /* used to close pipe input fd */ 497 if (close_fd >= 0 && (((flags & XPCLOSE) && cldpid) || 498 ((flags & XCCLOSE) && !cldpid))) 499 close(close_fd); 500 if (!cldpid) { 501 /* child */ 502 503 /* Do this before restoring signal */ 504 if (flags & XCOPROC) 505 coproc_cleanup(false); 506 cleanup_parents_env(); 507 #ifndef MKSH_UNEMPLOYED 508 /* 509 * If FMONITOR or FTALKING is set, these signals are ignored, 510 * if neither FMONITOR nor FTALKING are set, the signals have 511 * their inherited values. 512 */ 513 if (Flag(FMONITOR) && !(flags & XXCOM)) { 514 for (forksleep = NELEM(tt_sigs); --forksleep >= 0; ) 515 setsig(&sigtraps[tt_sigs[forksleep]], SIG_DFL, 516 SS_RESTORE_DFL|SS_FORCE); 517 } 518 #endif 519 #if HAVE_NICE 520 if (Flag(FBGNICE) && (flags & XBGND)) 521 ksh_nice(4); 522 #endif 523 if ((flags & XBGND) 524 #ifndef MKSH_UNEMPLOYED 525 && !Flag(FMONITOR) 526 #endif 527 ) { 528 setsig(&sigtraps[SIGINT], SIG_IGN, 529 SS_RESTORE_IGN|SS_FORCE); 530 setsig(&sigtraps[SIGQUIT], SIG_IGN, 531 SS_RESTORE_IGN|SS_FORCE); 532 if ((!(flags & (XPIPEI | XCOPROC))) && 533 ((forksleep = open("/dev/null", 0)) > 0)) { 534 (void)ksh_dup2(forksleep, 0, true); 535 close(forksleep); 536 } 537 } 538 /* in case of $(jobs) command */ 539 remove_job(j, "child"); 540 #ifndef MKSH_NOPROSPECTOFWORK 541 /* remove_job needs SIGCHLD blocked still */ 542 sigprocmask(SIG_SETMASK, &omask, NULL); 543 #endif 544 nzombie = 0; 545 #ifndef MKSH_UNEMPLOYED 546 ttypgrp_ok = false; 547 Flag(FMONITOR) = 0; 548 #endif 549 Flag(FTALKING) = 0; 550 cleartraps(); 551 /* no return */ 552 execute(t, (flags & XERROK) | XEXEC, NULL); 553 #ifndef MKSH_SMALL 554 if (t->type == TPIPE) 555 unwind(LLEAVE); 556 internal_warningf("%s: %s", "exchild", "execute() returned"); 557 fptreef(shl_out, 8, "%s: tried to execute {\n\t%T\n}\n", 558 "exchild", t); 559 shf_flush(shl_out); 560 #endif 561 unwind(LLEAVE); 562 /* NOTREACHED */ 563 } 564 565 /* shell (parent) stuff */ 566 if (!(flags & XPIPEO)) { 567 /* last process in a job */ 568 j_startjob(j); 569 if (flags & XCOPROC) { 570 j->coproc_id = coproc.id; 571 /* n jobs using co-process output */ 572 coproc.njobs++; 573 /* j using co-process input */ 574 coproc.job = (void *)j; 575 } 576 if (flags & XBGND) { 577 j_set_async(j); 578 if (Flag(FTALKING)) { 579 shf_fprintf(shl_out, "[%d]", j->job); 580 for (p = j->proc_list; p; p = p->next) 581 shf_fprintf(shl_out, " %d", 582 (int)p->pid); 583 shf_putchar('\n', shl_out); 584 shf_flush(shl_out); 585 } 586 } else 587 rv = j_waitj(j, jwflags, "jw:last proc"); 588 } 589 590 #ifndef MKSH_NOPROSPECTOFWORK 591 sigprocmask(SIG_SETMASK, &omask, NULL); 592 #endif 593 594 return (rv); 595 } 596 597 /* start the last job: only used for $(command) jobs */ 598 void 599 startlast(void) 600 { 601 #ifndef MKSH_NOPROSPECTOFWORK 602 sigset_t omask; 603 604 sigprocmask(SIG_BLOCK, &sm_sigchld, &omask); 605 #endif 606 607 /* no need to report error - waitlast() will do it */ 608 if (last_job) { 609 /* ensure it isn't removed by check_job() */ 610 last_job->flags |= JF_WAITING; 611 j_startjob(last_job); 612 } 613 #ifndef MKSH_NOPROSPECTOFWORK 614 sigprocmask(SIG_SETMASK, &omask, NULL); 615 #endif 616 } 617 618 /* wait for last job: only used for $(command) jobs */ 619 int 620 waitlast(void) 621 { 622 int rv; 623 Job *j; 624 #ifndef MKSH_NOPROSPECTOFWORK 625 sigset_t omask; 626 627 sigprocmask(SIG_BLOCK, &sm_sigchld, &omask); 628 #endif 629 630 j = last_job; 631 if (!j || !(j->flags & JF_STARTED)) { 632 if (!j) 633 warningf(true, "%s: %s", "waitlast", "no last job"); 634 else 635 internal_warningf("%s: %s", "waitlast", "not started"); 636 #ifndef MKSH_NOPROSPECTOFWORK 637 sigprocmask(SIG_SETMASK, &omask, NULL); 638 #endif 639 /* not so arbitrary, non-zero value */ 640 return (125); 641 } 642 643 rv = j_waitj(j, JW_NONE, "waitlast"); 644 645 #ifndef MKSH_NOPROSPECTOFWORK 646 sigprocmask(SIG_SETMASK, &omask, NULL); 647 #endif 648 649 return (rv); 650 } 651 652 /* wait for child, interruptable. */ 653 int 654 waitfor(const char *cp, int *sigp) 655 { 656 int rv, ecode, flags = JW_INTERRUPT|JW_ASYNCNOTIFY; 657 Job *j; 658 #ifndef MKSH_NOPROSPECTOFWORK 659 sigset_t omask; 660 661 sigprocmask(SIG_BLOCK, &sm_sigchld, &omask); 662 #endif 663 664 *sigp = 0; 665 666 if (cp == NULL) { 667 /* 668 * wait for an unspecified job - always returns 0, so 669 * don't have to worry about exited/signaled jobs 670 */ 671 for (j = job_list; j; j = j->next) 672 /* AT&T ksh will wait for stopped jobs - we don't */ 673 if (j->ppid == procpid && j->state == PRUNNING) 674 break; 675 if (!j) { 676 #ifndef MKSH_NOPROSPECTOFWORK 677 sigprocmask(SIG_SETMASK, &omask, NULL); 678 #endif 679 return (-1); 680 } 681 } else if ((j = j_lookup(cp, &ecode))) { 682 /* don't report normal job completion */ 683 flags &= ~JW_ASYNCNOTIFY; 684 if (j->ppid != procpid) { 685 #ifndef MKSH_NOPROSPECTOFWORK 686 sigprocmask(SIG_SETMASK, &omask, NULL); 687 #endif 688 return (-1); 689 } 690 } else { 691 #ifndef MKSH_NOPROSPECTOFWORK 692 sigprocmask(SIG_SETMASK, &omask, NULL); 693 #endif 694 if (ecode != JL_NOSUCH) 695 bi_errorf("%s: %s", cp, lookup_msgs[ecode]); 696 return (-1); 697 } 698 699 /* AT&T ksh will wait for stopped jobs - we don't */ 700 rv = j_waitj(j, flags, "jw:waitfor"); 701 702 #ifndef MKSH_NOPROSPECTOFWORK 703 sigprocmask(SIG_SETMASK, &omask, NULL); 704 #endif 705 706 if (rv < 0) 707 /* we were interrupted */ 708 *sigp = 128 + -rv; 709 710 return (rv); 711 } 712 713 /* kill (built-in) a job */ 714 int 715 j_kill(const char *cp, int sig) 716 { 717 Job *j; 718 int rv = 0, ecode; 719 #ifndef MKSH_NOPROSPECTOFWORK 720 sigset_t omask; 721 722 sigprocmask(SIG_BLOCK, &sm_sigchld, &omask); 723 #endif 724 725 if ((j = j_lookup(cp, &ecode)) == NULL) { 726 #ifndef MKSH_NOPROSPECTOFWORK 727 sigprocmask(SIG_SETMASK, &omask, NULL); 728 #endif 729 bi_errorf("%s: %s", cp, lookup_msgs[ecode]); 730 return (1); 731 } 732 733 if (j->pgrp == 0) { 734 /* started when !Flag(FMONITOR) */ 735 if (kill_job(j, sig) < 0) { 736 bi_errorf("%s: %s", cp, cstrerror(errno)); 737 rv = 1; 738 } 739 } else { 740 #ifndef MKSH_UNEMPLOYED 741 if (j->state == PSTOPPED && (sig == SIGTERM || sig == SIGHUP)) 742 mksh_killpg(j->pgrp, SIGCONT); 743 #endif 744 if (mksh_killpg(j->pgrp, sig) < 0) { 745 bi_errorf("%s: %s", cp, cstrerror(errno)); 746 rv = 1; 747 } 748 } 749 750 #ifndef MKSH_NOPROSPECTOFWORK 751 sigprocmask(SIG_SETMASK, &omask, NULL); 752 #endif 753 754 return (rv); 755 } 756 757 #ifndef MKSH_UNEMPLOYED 758 /* fg and bg built-ins: called only if Flag(FMONITOR) set */ 759 int 760 j_resume(const char *cp, int bg) 761 { 762 Job *j; 763 Proc *p; 764 int ecode, rv = 0; 765 bool running; 766 sigset_t omask; 767 768 sigprocmask(SIG_BLOCK, &sm_sigchld, &omask); 769 770 if ((j = j_lookup(cp, &ecode)) == NULL) { 771 sigprocmask(SIG_SETMASK, &omask, NULL); 772 bi_errorf("%s: %s", cp, lookup_msgs[ecode]); 773 return (1); 774 } 775 776 if (j->pgrp == 0) { 777 sigprocmask(SIG_SETMASK, &omask, NULL); 778 bi_errorf("job not job-controlled"); 779 return (1); 780 } 781 782 if (bg) 783 shprintf("[%d] ", j->job); 784 785 running = false; 786 for (p = j->proc_list; p != NULL; p = p->next) { 787 if (p->state == PSTOPPED) { 788 p->state = PRUNNING; 789 p->status = 0; 790 running = true; 791 } 792 shf_puts(p->command, shl_stdout); 793 if (p->next) 794 shf_puts("| ", shl_stdout); 795 } 796 shf_putc('\n', shl_stdout); 797 shf_flush(shl_stdout); 798 if (running) 799 j->state = PRUNNING; 800 801 put_job(j, PJ_PAST_STOPPED); 802 if (bg) 803 j_set_async(j); 804 else { 805 /* attach tty to job */ 806 if (j->state == PRUNNING) { 807 if (ttypgrp_ok && (j->flags & JF_SAVEDTTY)) 808 mksh_tcset(tty_fd, &j->ttystat); 809 /* See comment in j_waitj regarding saved_ttypgrp. */ 810 if (ttypgrp_ok && 811 tcsetpgrp(tty_fd, (j->flags & JF_SAVEDTTYPGRP) ? 812 j->saved_ttypgrp : j->pgrp) < 0) { 813 rv = errno; 814 if (j->flags & JF_SAVEDTTY) 815 mksh_tcset(tty_fd, &tty_state); 816 sigprocmask(SIG_SETMASK, &omask, NULL); 817 bi_errorf("%s %s(%d, %ld) %s: %s", 818 "1st", "tcsetpgrp", tty_fd, 819 (long)((j->flags & JF_SAVEDTTYPGRP) ? 820 j->saved_ttypgrp : j->pgrp), "failed", 821 cstrerror(rv)); 822 return (1); 823 } 824 } 825 j->flags |= JF_FG; 826 j->flags &= ~JF_KNOWN; 827 if (j == async_job) 828 async_job = NULL; 829 } 830 831 if (j->state == PRUNNING && mksh_killpg(j->pgrp, SIGCONT) < 0) { 832 int eno = errno; 833 834 if (!bg) { 835 j->flags &= ~JF_FG; 836 if (ttypgrp_ok && (j->flags & JF_SAVEDTTY)) 837 mksh_tcset(tty_fd, &tty_state); 838 if (ttypgrp_ok && tcsetpgrp(tty_fd, kshpgrp) < 0) 839 warningf(true, "%s %s(%d, %ld) %s: %s", 840 "fg: 2nd", "tcsetpgrp", tty_fd, 841 (long)kshpgrp, "failed", cstrerror(errno)); 842 } 843 sigprocmask(SIG_SETMASK, &omask, NULL); 844 bi_errorf("%s %s %s", "can't continue job", 845 cp, cstrerror(eno)); 846 return (1); 847 } 848 if (!bg) { 849 if (ttypgrp_ok) { 850 j->flags &= ~(JF_SAVEDTTY | JF_SAVEDTTYPGRP); 851 } 852 rv = j_waitj(j, JW_NONE, "jw:resume"); 853 } 854 sigprocmask(SIG_SETMASK, &omask, NULL); 855 return (rv); 856 } 857 #endif 858 859 /* are there any running or stopped jobs ? */ 860 int 861 j_stopped_running(void) 862 { 863 Job *j; 864 int which = 0; 865 866 for (j = job_list; j != NULL; j = j->next) { 867 #ifndef MKSH_UNEMPLOYED 868 if (j->ppid == procpid && j->state == PSTOPPED) 869 which |= 1; 870 #endif 871 if (Flag(FLOGIN) && !Flag(FNOHUP) && procpid == kshpid && 872 j->ppid == procpid && j->state == PRUNNING) 873 which |= 2; 874 } 875 if (which) { 876 shellf("You have %s%s%s jobs\n", 877 which & 1 ? "stopped" : "", 878 which == 3 ? " and " : "", 879 which & 2 ? "running" : ""); 880 return (1); 881 } 882 883 return (0); 884 } 885 886 887 /* list jobs for jobs built-in */ 888 int 889 j_jobs(const char *cp, int slp, 890 /* 0: short, 1: long, 2: pgrp */ 891 int nflag) 892 { 893 Job *j, *tmp; 894 int how, zflag = 0; 895 #ifndef MKSH_NOPROSPECTOFWORK 896 sigset_t omask; 897 898 sigprocmask(SIG_BLOCK, &sm_sigchld, &omask); 899 #endif 900 901 if (nflag < 0) { 902 /* kludge: print zombies */ 903 nflag = 0; 904 zflag = 1; 905 } 906 if (cp) { 907 int ecode; 908 909 if ((j = j_lookup(cp, &ecode)) == NULL) { 910 #ifndef MKSH_NOPROSPECTOFWORK 911 sigprocmask(SIG_SETMASK, &omask, NULL); 912 #endif 913 bi_errorf("%s: %s", cp, lookup_msgs[ecode]); 914 return (1); 915 } 916 } else 917 j = job_list; 918 how = slp == 0 ? JP_MEDIUM : (slp == 1 ? JP_LONG : JP_PGRP); 919 for (; j; j = j->next) { 920 if ((!(j->flags & JF_ZOMBIE) || zflag) && 921 (!nflag || (j->flags & JF_CHANGED))) { 922 j_print(j, how, shl_stdout); 923 if (j->state == PEXITED || j->state == PSIGNALLED) 924 j->flags |= JF_REMOVE; 925 } 926 if (cp) 927 break; 928 } 929 /* Remove jobs after printing so there won't be multiple + or - jobs */ 930 for (j = job_list; j; j = tmp) { 931 tmp = j->next; 932 if (j->flags & JF_REMOVE) 933 remove_job(j, "jobs"); 934 } 935 #ifndef MKSH_NOPROSPECTOFWORK 936 sigprocmask(SIG_SETMASK, &omask, NULL); 937 #endif 938 return (0); 939 } 940 941 /* list jobs for top-level notification */ 942 void 943 j_notify(void) 944 { 945 Job *j, *tmp; 946 #ifndef MKSH_NOPROSPECTOFWORK 947 sigset_t omask; 948 949 sigprocmask(SIG_BLOCK, &sm_sigchld, &omask); 950 #endif 951 for (j = job_list; j; j = j->next) { 952 #ifndef MKSH_UNEMPLOYED 953 if (Flag(FMONITOR) && (j->flags & JF_CHANGED)) 954 j_print(j, JP_MEDIUM, shl_out); 955 #endif 956 /* 957 * Remove job after doing reports so there aren't 958 * multiple +/- jobs. 959 */ 960 if (j->state == PEXITED || j->state == PSIGNALLED) 961 j->flags |= JF_REMOVE; 962 } 963 for (j = job_list; j; j = tmp) { 964 tmp = j->next; 965 if (j->flags & JF_REMOVE) 966 remove_job(j, "notify"); 967 } 968 shf_flush(shl_out); 969 #ifndef MKSH_NOPROSPECTOFWORK 970 sigprocmask(SIG_SETMASK, &omask, NULL); 971 #endif 972 } 973 974 /* Return pid of last process in last asynchronous job */ 975 pid_t 976 j_async(void) 977 { 978 #ifndef MKSH_NOPROSPECTOFWORK 979 sigset_t omask; 980 981 sigprocmask(SIG_BLOCK, &sm_sigchld, &omask); 982 #endif 983 984 if (async_job) 985 async_job->flags |= JF_KNOWN; 986 987 #ifndef MKSH_NOPROSPECTOFWORK 988 sigprocmask(SIG_SETMASK, &omask, NULL); 989 #endif 990 991 return (async_pid); 992 } 993 994 /* 995 * Make j the last async process 996 * 997 * If jobs are compiled in then this routine expects sigchld to be blocked. 998 */ 999 static void 1000 j_set_async(Job *j) 1001 { 1002 Job *jl, *oldest; 1003 1004 if (async_job && (async_job->flags & (JF_KNOWN|JF_ZOMBIE)) == JF_ZOMBIE) 1005 remove_job(async_job, "async"); 1006 if (!(j->flags & JF_STARTED)) { 1007 internal_warningf("%s: %s", "j_async", "job not started"); 1008 return; 1009 } 1010 async_job = j; 1011 async_pid = j->last_proc->pid; 1012 while (nzombie > CHILD_MAX) { 1013 oldest = NULL; 1014 for (jl = job_list; jl; jl = jl->next) 1015 if (jl != async_job && (jl->flags & JF_ZOMBIE) && 1016 (!oldest || jl->age < oldest->age)) 1017 oldest = jl; 1018 if (!oldest) { 1019 /* XXX debugging */ 1020 if (!(async_job->flags & JF_ZOMBIE) || nzombie != 1) { 1021 internal_warningf("%s: bad nzombie (%d)", 1022 "j_async", nzombie); 1023 nzombie = 0; 1024 } 1025 break; 1026 } 1027 remove_job(oldest, "zombie"); 1028 } 1029 } 1030 1031 /* 1032 * Start a job: set STARTED, check for held signals and set j->last_proc 1033 * 1034 * If jobs are compiled in then this routine expects sigchld to be blocked. 1035 */ 1036 static void 1037 j_startjob(Job *j) 1038 { 1039 Proc *p; 1040 1041 j->flags |= JF_STARTED; 1042 for (p = j->proc_list; p->next; p = p->next) 1043 ; 1044 j->last_proc = p; 1045 1046 #ifndef MKSH_NOPROSPECTOFWORK 1047 if (held_sigchld) { 1048 held_sigchld = 0; 1049 /* Don't call j_sigchld() as it may remove job... */ 1050 kill(procpid, SIGCHLD); 1051 } 1052 #endif 1053 } 1054 1055 /* 1056 * wait for job to complete or change state 1057 * 1058 * If jobs are compiled in then this routine expects sigchld to be blocked. 1059 */ 1060 static int 1061 j_waitj(Job *j, 1062 /* see JW_* */ 1063 int flags, 1064 const char *where) 1065 { 1066 int rv; 1067 #ifdef MKSH_NO_SIGSUSPEND 1068 sigset_t omask; 1069 #endif 1070 1071 /* 1072 * No auto-notify on the job we are waiting on. 1073 */ 1074 j->flags |= JF_WAITING; 1075 if (flags & JW_ASYNCNOTIFY) 1076 j->flags |= JF_W_ASYNCNOTIFY; 1077 1078 #ifndef MKSH_UNEMPLOYED 1079 if (!Flag(FMONITOR)) 1080 #endif 1081 flags |= JW_STOPPEDWAIT; 1082 1083 while (j->state == PRUNNING || 1084 ((flags & JW_STOPPEDWAIT) && j->state == PSTOPPED)) { 1085 #ifndef MKSH_NOPROSPECTOFWORK 1086 #ifdef MKSH_NO_SIGSUSPEND 1087 sigprocmask(SIG_SETMASK, &sm_default, &omask); 1088 pause(); 1089 /* note that handlers may run here so they need to know */ 1090 sigprocmask(SIG_SETMASK, &omask, NULL); 1091 #else 1092 sigsuspend(&sm_default); 1093 #endif 1094 #else 1095 j_sigchld(SIGCHLD); 1096 #endif 1097 if (fatal_trap) { 1098 int oldf = j->flags & (JF_WAITING|JF_W_ASYNCNOTIFY); 1099 j->flags &= ~(JF_WAITING|JF_W_ASYNCNOTIFY); 1100 runtraps(TF_FATAL); 1101 /* not reached... */ 1102 j->flags |= oldf; 1103 } 1104 if ((flags & JW_INTERRUPT) && (rv = trap_pending())) { 1105 j->flags &= ~(JF_WAITING|JF_W_ASYNCNOTIFY); 1106 return (-rv); 1107 } 1108 } 1109 j->flags &= ~(JF_WAITING|JF_W_ASYNCNOTIFY); 1110 1111 if (j->flags & JF_FG) { 1112 j->flags &= ~JF_FG; 1113 #ifndef MKSH_UNEMPLOYED 1114 if (Flag(FMONITOR) && ttypgrp_ok && j->pgrp) { 1115 /* 1116 * Save the tty's current pgrp so it can be restored 1117 * when the job is foregrounded. This is to 1118 * deal with things like the GNU su which does 1119 * a fork/exec instead of an exec (the fork means 1120 * the execed shell gets a different pid from its 1121 * pgrp, so naturally it sets its pgrp and gets hosed 1122 * when it gets foregrounded by the parent shell which 1123 * has restored the tty's pgrp to that of the su 1124 * process). 1125 */ 1126 if (j->state == PSTOPPED && 1127 (j->saved_ttypgrp = tcgetpgrp(tty_fd)) >= 0) 1128 j->flags |= JF_SAVEDTTYPGRP; 1129 if (tcsetpgrp(tty_fd, kshpgrp) < 0) 1130 warningf(true, "%s %s(%d, %ld) %s: %s", 1131 "j_waitj:", "tcsetpgrp", tty_fd, 1132 (long)kshpgrp, "failed", cstrerror(errno)); 1133 if (j->state == PSTOPPED) { 1134 j->flags |= JF_SAVEDTTY; 1135 mksh_tcget(tty_fd, &j->ttystat); 1136 } 1137 } 1138 #endif 1139 if (tty_hasstate) { 1140 /* 1141 * Only restore tty settings if job was originally 1142 * started in the foreground. Problems can be 1143 * caused by things like 'more foobar &' which will 1144 * typically get and save the shell's vi/emacs tty 1145 * settings before setting up the tty for itself; 1146 * when more exits, it restores the 'original' 1147 * settings, and things go down hill from there... 1148 */ 1149 if (j->state == PEXITED && j->status == 0 && 1150 (j->flags & JF_USETTYMODE)) { 1151 mksh_tcget(tty_fd, &tty_state); 1152 } else { 1153 mksh_tcset(tty_fd, &tty_state); 1154 /*- 1155 * Don't use tty mode if job is stopped and 1156 * later restarted and exits. Consider 1157 * the sequence: 1158 * vi foo (stopped) 1159 * ... 1160 * stty something 1161 * ... 1162 * fg (vi; ZZ) 1163 * mode should be that of the stty, not what 1164 * was before the vi started. 1165 */ 1166 if (j->state == PSTOPPED) 1167 j->flags &= ~JF_USETTYMODE; 1168 } 1169 } 1170 #ifndef MKSH_UNEMPLOYED 1171 /* 1172 * If it looks like user hit ^C to kill a job, pretend we got 1173 * one too to break out of for loops, etc. (AT&T ksh does this 1174 * even when not monitoring, but this doesn't make sense since 1175 * a tty generated ^C goes to the whole process group) 1176 */ 1177 { 1178 int status; 1179 1180 status = j->last_proc->status; 1181 if (Flag(FMONITOR) && j->state == PSIGNALLED && 1182 WIFSIGNALED(status) && 1183 (sigtraps[WTERMSIG(status)].flags & TF_TTY_INTR)) 1184 trapsig(WTERMSIG(status)); 1185 } 1186 #endif 1187 } 1188 1189 j_usrtime = j->usrtime; 1190 j_systime = j->systime; 1191 rv = j->status; 1192 1193 if ((flags & JW_PIPEST) && (j->proc_list != NULL)) { 1194 uint32_t num = 0; 1195 Proc *p = j->proc_list; 1196 struct tbl *vp; 1197 1198 unset(vp_pipest, 1); 1199 vp = vp_pipest; 1200 vp->flag = DEFINED | ISSET | INTEGER | RDONLY | ARRAY | INT_U; 1201 goto got_array; 1202 1203 while (p != NULL) { 1204 { 1205 struct tbl *vq; 1206 1207 /* strlen(vp_pipest->name) == 10 */ 1208 vq = alloc(offsetof(struct tbl, name[0]) + 11, 1209 vp_pipest->areap); 1210 memset(vq, 0, offsetof(struct tbl, name[0])); 1211 memcpy(vq->name, vp_pipest->name, 11); 1212 vp->u.array = vq; 1213 vp = vq; 1214 } 1215 vp->areap = vp_pipest->areap; 1216 vp->ua.index = ++num; 1217 vp->flag = DEFINED | ISSET | INTEGER | RDONLY | 1218 ARRAY | INT_U | AINDEX; 1219 got_array: 1220 vp->val.i = proc_errorlevel(p); 1221 if (Flag(FPIPEFAIL) && vp->val.i) 1222 rv = vp->val.i; 1223 p = p->next; 1224 } 1225 } 1226 1227 if (!(flags & JW_ASYNCNOTIFY) 1228 #ifndef MKSH_UNEMPLOYED 1229 && (!Flag(FMONITOR) || j->state != PSTOPPED) 1230 #endif 1231 ) { 1232 j_print(j, JP_SHORT, shl_out); 1233 shf_flush(shl_out); 1234 } 1235 if (j->state != PSTOPPED 1236 #ifndef MKSH_UNEMPLOYED 1237 && (!Flag(FMONITOR) || !(flags & JW_ASYNCNOTIFY)) 1238 #endif 1239 ) 1240 remove_job(j, where); 1241 1242 return (rv); 1243 } 1244 1245 /* 1246 * SIGCHLD handler to reap children and update job states 1247 * 1248 * If jobs are compiled in then this routine expects sigchld to be blocked. 1249 */ 1250 /* ARGSUSED */ 1251 static void 1252 j_sigchld(int sig MKSH_A_UNUSED) 1253 { 1254 int saved_errno = errno; 1255 Job *j; 1256 Proc *p = NULL; 1257 pid_t pid; 1258 int status; 1259 struct rusage ru0, ru1; 1260 #ifdef MKSH_NO_SIGSUSPEND 1261 sigset_t omask; 1262 1263 /* this handler can run while SIGCHLD is not blocked, so block it now */ 1264 sigprocmask(SIG_BLOCK, &sm_sigchld, &omask); 1265 #endif 1266 1267 #ifndef MKSH_NOPROSPECTOFWORK 1268 /* 1269 * Don't wait for any processes if a job is partially started. 1270 * This is so we don't do away with the process group leader 1271 * before all the processes in a pipe line are started (so the 1272 * setpgid() won't fail) 1273 */ 1274 for (j = job_list; j; j = j->next) 1275 if (j->ppid == procpid && !(j->flags & JF_STARTED)) { 1276 held_sigchld = 1; 1277 goto j_sigchld_out; 1278 } 1279 #endif 1280 1281 getrusage(RUSAGE_CHILDREN, &ru0); 1282 do { 1283 #ifndef MKSH_NOPROSPECTOFWORK 1284 pid = waitpid(-1, &status, (WNOHANG|WUNTRACED)); 1285 #else 1286 pid = wait(&status); 1287 #endif 1288 1289 /* 1290 * return if this would block (0) or no children 1291 * or interrupted (-1) 1292 */ 1293 if (pid <= 0) 1294 goto j_sigchld_out; 1295 1296 getrusage(RUSAGE_CHILDREN, &ru1); 1297 1298 /* find job and process structures for this pid */ 1299 for (j = job_list; j != NULL; j = j->next) 1300 for (p = j->proc_list; p != NULL; p = p->next) 1301 if (p->pid == pid) 1302 goto found; 1303 found: 1304 if (j == NULL) { 1305 /* Can occur if process has kids, then execs shell 1306 warningf(true, "bad process waited for (pid = %d)", 1307 pid); 1308 */ 1309 ru0 = ru1; 1310 continue; 1311 } 1312 1313 timeradd(&j->usrtime, &ru1.ru_utime, &j->usrtime); 1314 timersub(&j->usrtime, &ru0.ru_utime, &j->usrtime); 1315 timeradd(&j->systime, &ru1.ru_stime, &j->systime); 1316 timersub(&j->systime, &ru0.ru_stime, &j->systime); 1317 ru0 = ru1; 1318 p->status = status; 1319 #ifndef MKSH_UNEMPLOYED 1320 if (WIFSTOPPED(status)) 1321 p->state = PSTOPPED; 1322 else 1323 #endif 1324 if (WIFSIGNALED(status)) 1325 p->state = PSIGNALLED; 1326 else 1327 p->state = PEXITED; 1328 1329 /* check to see if entire job is done */ 1330 check_job(j); 1331 } 1332 #ifndef MKSH_NOPROSPECTOFWORK 1333 while (/* CONSTCOND */ 1); 1334 #else 1335 while (/* CONSTCOND */ 0); 1336 #endif 1337 1338 j_sigchld_out: 1339 #ifdef MKSH_NO_SIGSUSPEND 1340 sigprocmask(SIG_SETMASK, &omask, NULL); 1341 #endif 1342 errno = saved_errno; 1343 } 1344 1345 /* 1346 * Called only when a process in j has exited/stopped (ie, called only 1347 * from j_sigchld()). If no processes are running, the job status 1348 * and state are updated, asynchronous job notification is done and, 1349 * if unneeded, the job is removed. 1350 * 1351 * If jobs are compiled in then this routine expects sigchld to be blocked. 1352 */ 1353 static void 1354 check_job(Job *j) 1355 { 1356 int jstate; 1357 Proc *p; 1358 1359 /* XXX debugging (nasty - interrupt routine using shl_out) */ 1360 if (!(j->flags & JF_STARTED)) { 1361 internal_warningf("check_job: job started (flags 0x%x)", 1362 j->flags); 1363 return; 1364 } 1365 1366 jstate = PRUNNING; 1367 for (p=j->proc_list; p != NULL; p = p->next) { 1368 if (p->state == PRUNNING) 1369 /* some processes still running */ 1370 return; 1371 if (p->state > jstate) 1372 jstate = p->state; 1373 } 1374 j->state = jstate; 1375 j->status = proc_errorlevel(j->last_proc); 1376 1377 /* 1378 * Note when co-process dies: can't be done in j_wait() nor 1379 * remove_job() since neither may be called for non-interactive 1380 * shells. 1381 */ 1382 if (j->state == PEXITED || j->state == PSIGNALLED) { 1383 /* 1384 * No need to keep co-process input any more 1385 * (at least, this is what ksh93d thinks) 1386 */ 1387 if (coproc.job == j) { 1388 coproc.job = NULL; 1389 /* 1390 * XXX would be nice to get the closes out of here 1391 * so they aren't done in the signal handler. 1392 * Would mean a check in coproc_getfd() to 1393 * do "if job == 0 && write >= 0, close write". 1394 */ 1395 coproc_write_close(coproc.write); 1396 } 1397 /* Do we need to keep the output? */ 1398 if (j->coproc_id && j->coproc_id == coproc.id && 1399 --coproc.njobs == 0) 1400 coproc_readw_close(coproc.read); 1401 } 1402 1403 j->flags |= JF_CHANGED; 1404 #ifndef MKSH_UNEMPLOYED 1405 if (Flag(FMONITOR) && !(j->flags & JF_XXCOM)) { 1406 /* 1407 * Only put stopped jobs at the front to avoid confusing 1408 * the user (don't want finished jobs effecting %+ or %-) 1409 */ 1410 if (j->state == PSTOPPED) 1411 put_job(j, PJ_ON_FRONT); 1412 if (Flag(FNOTIFY) && 1413 (j->flags & (JF_WAITING|JF_W_ASYNCNOTIFY)) != JF_WAITING) { 1414 /* Look for the real file descriptor 2 */ 1415 { 1416 struct env *ep; 1417 int fd = 2; 1418 1419 for (ep = e; ep; ep = ep->oenv) 1420 if (ep->savefd && ep->savefd[2]) 1421 fd = ep->savefd[2]; 1422 shf_reopen(fd, SHF_WR, shl_j); 1423 } 1424 /* 1425 * Can't call j_notify() as it removes jobs. The job 1426 * must stay in the job list as j_waitj() may be 1427 * running with this job. 1428 */ 1429 j_print(j, JP_MEDIUM, shl_j); 1430 shf_flush(shl_j); 1431 if (!(j->flags & JF_WAITING) && j->state != PSTOPPED) 1432 remove_job(j, "notify"); 1433 } 1434 } 1435 #endif 1436 if ( 1437 #ifndef MKSH_UNEMPLOYED 1438 !Flag(FMONITOR) && 1439 #endif 1440 !(j->flags & (JF_WAITING|JF_FG)) && 1441 j->state != PSTOPPED) { 1442 if (j == async_job || (j->flags & JF_KNOWN)) { 1443 j->flags |= JF_ZOMBIE; 1444 j->job = -1; 1445 nzombie++; 1446 } else 1447 remove_job(j, "checkjob"); 1448 } 1449 } 1450 1451 /* 1452 * Print job status in either short, medium or long format. 1453 * 1454 * If jobs are compiled in then this routine expects sigchld to be blocked. 1455 */ 1456 static void 1457 j_print(Job *j, int how, struct shf *shf) 1458 { 1459 Proc *p; 1460 int state; 1461 int status; 1462 int coredumped; 1463 char jobchar = ' '; 1464 char buf[64]; 1465 const char *filler; 1466 int output = 0; 1467 1468 if (how == JP_PGRP) { 1469 /* 1470 * POSIX doesn't say what to do it there is no process 1471 * group leader (ie, !FMONITOR). We arbitrarily return 1472 * last pid (which is what $! returns). 1473 */ 1474 shf_fprintf(shf, "%d\n", (int)(j->pgrp ? j->pgrp : 1475 (j->last_proc ? j->last_proc->pid : 0))); 1476 return; 1477 } 1478 j->flags &= ~JF_CHANGED; 1479 filler = j->job > 10 ? "\n " : "\n "; 1480 if (j == job_list) 1481 jobchar = '+'; 1482 else if (j == job_list->next) 1483 jobchar = '-'; 1484 1485 for (p = j->proc_list; p != NULL;) { 1486 coredumped = 0; 1487 switch (p->state) { 1488 case PRUNNING: 1489 memcpy(buf, "Running", 8); 1490 break; 1491 case PSTOPPED: 1492 strlcpy(buf, sigtraps[WSTOPSIG(p->status)].mess, 1493 sizeof(buf)); 1494 break; 1495 case PEXITED: 1496 if (how == JP_SHORT) 1497 buf[0] = '\0'; 1498 else if (WEXITSTATUS(p->status) == 0) 1499 memcpy(buf, "Done", 5); 1500 else 1501 shf_snprintf(buf, sizeof(buf), "Done (%d)", 1502 WEXITSTATUS(p->status)); 1503 break; 1504 case PSIGNALLED: 1505 #ifdef WCOREDUMP 1506 if (WCOREDUMP(p->status)) 1507 coredumped = 1; 1508 #endif 1509 /* 1510 * kludge for not reporting 'normal termination 1511 * signals' (i.e. SIGINT, SIGPIPE) 1512 */ 1513 if (how == JP_SHORT && !coredumped && 1514 (WTERMSIG(p->status) == SIGINT || 1515 WTERMSIG(p->status) == SIGPIPE)) { 1516 buf[0] = '\0'; 1517 } else 1518 strlcpy(buf, sigtraps[WTERMSIG(p->status)].mess, 1519 sizeof(buf)); 1520 break; 1521 default: 1522 buf[0] = '\0'; 1523 } 1524 1525 if (how != JP_SHORT) { 1526 if (p == j->proc_list) 1527 shf_fprintf(shf, "[%d] %c ", j->job, jobchar); 1528 else 1529 shf_puts(filler, shf); 1530 } 1531 1532 if (how == JP_LONG) 1533 shf_fprintf(shf, "%5d ", (int)p->pid); 1534 1535 if (how == JP_SHORT) { 1536 if (buf[0]) { 1537 output = 1; 1538 shf_fprintf(shf, "%s%s ", 1539 buf, coredumped ? " (core dumped)" : null); 1540 } 1541 } else { 1542 output = 1; 1543 shf_fprintf(shf, "%-20s %s%s%s", buf, p->command, 1544 p->next ? "|" : null, 1545 coredumped ? " (core dumped)" : null); 1546 } 1547 1548 state = p->state; 1549 status = p->status; 1550 p = p->next; 1551 while (p && p->state == state && p->status == status) { 1552 if (how == JP_LONG) 1553 shf_fprintf(shf, "%s%5d %-20s %s%s", filler, 1554 (int)p->pid, " ", p->command, 1555 p->next ? "|" : null); 1556 else if (how == JP_MEDIUM) 1557 shf_fprintf(shf, " %s%s", p->command, 1558 p->next ? "|" : null); 1559 p = p->next; 1560 } 1561 } 1562 if (output) 1563 shf_putc('\n', shf); 1564 } 1565 1566 /* 1567 * Convert % sequence to job 1568 * 1569 * If jobs are compiled in then this routine expects sigchld to be blocked. 1570 */ 1571 static Job * 1572 j_lookup(const char *cp, int *ecodep) 1573 { 1574 Job *j, *last_match; 1575 Proc *p; 1576 size_t len; 1577 int job = 0; 1578 1579 if (ksh_isdigit(*cp)) { 1580 getn(cp, &job); 1581 /* Look for last_proc->pid (what $! returns) first... */ 1582 for (j = job_list; j != NULL; j = j->next) 1583 if (j->last_proc && j->last_proc->pid == job) 1584 return (j); 1585 /* 1586 * ...then look for process group (this is non-POSIX, 1587 * but should not break anything 1588 */ 1589 for (j = job_list; j != NULL; j = j->next) 1590 if (j->pgrp && j->pgrp == job) 1591 return (j); 1592 if (ecodep) 1593 *ecodep = JL_NOSUCH; 1594 return (NULL); 1595 } 1596 if (*cp != '%') { 1597 if (ecodep) 1598 *ecodep = JL_INVALID; 1599 return (NULL); 1600 } 1601 switch (*++cp) { 1602 case '\0': /* non-standard */ 1603 case '+': 1604 case '%': 1605 if (job_list != NULL) 1606 return (job_list); 1607 break; 1608 1609 case '-': 1610 if (job_list != NULL && job_list->next) 1611 return (job_list->next); 1612 break; 1613 1614 case '0': case '1': case '2': case '3': case '4': 1615 case '5': case '6': case '7': case '8': case '9': 1616 getn(cp, &job); 1617 for (j = job_list; j != NULL; j = j->next) 1618 if (j->job == job) 1619 return (j); 1620 break; 1621 1622 /* %?string */ 1623 case '?': 1624 last_match = NULL; 1625 for (j = job_list; j != NULL; j = j->next) 1626 for (p = j->proc_list; p != NULL; p = p->next) 1627 if (strstr(p->command, cp+1) != NULL) { 1628 if (last_match) { 1629 if (ecodep) 1630 *ecodep = JL_AMBIG; 1631 return (NULL); 1632 } 1633 last_match = j; 1634 } 1635 if (last_match) 1636 return (last_match); 1637 break; 1638 1639 /* %string */ 1640 default: 1641 len = strlen(cp); 1642 last_match = NULL; 1643 for (j = job_list; j != NULL; j = j->next) 1644 if (strncmp(cp, j->proc_list->command, len) == 0) { 1645 if (last_match) { 1646 if (ecodep) 1647 *ecodep = JL_AMBIG; 1648 return (NULL); 1649 } 1650 last_match = j; 1651 } 1652 if (last_match) 1653 return (last_match); 1654 break; 1655 } 1656 if (ecodep) 1657 *ecodep = JL_NOSUCH; 1658 return (NULL); 1659 } 1660 1661 static Job *free_jobs; 1662 static Proc *free_procs; 1663 1664 /* 1665 * allocate a new job and fill in the job number. 1666 * 1667 * If jobs are compiled in then this routine expects sigchld to be blocked. 1668 */ 1669 static Job * 1670 new_job(void) 1671 { 1672 int i; 1673 Job *newj, *j; 1674 1675 if (free_jobs != NULL) { 1676 newj = free_jobs; 1677 free_jobs = free_jobs->next; 1678 } else 1679 newj = alloc(sizeof(Job), APERM); 1680 1681 /* brute force method */ 1682 for (i = 1; ; i++) { 1683 for (j = job_list; j && j->job != i; j = j->next) 1684 ; 1685 if (j == NULL) 1686 break; 1687 } 1688 newj->job = i; 1689 1690 return (newj); 1691 } 1692 1693 /* 1694 * Allocate new process struct 1695 * 1696 * If jobs are compiled in then this routine expects sigchld to be blocked. 1697 */ 1698 static Proc * 1699 new_proc(void) 1700 { 1701 Proc *p; 1702 1703 if (free_procs != NULL) { 1704 p = free_procs; 1705 free_procs = free_procs->next; 1706 } else 1707 p = alloc(sizeof(Proc), APERM); 1708 1709 return (p); 1710 } 1711 1712 /* 1713 * Take job out of job_list and put old structures into free list. 1714 * Keeps nzombies, last_job and async_job up to date. 1715 * 1716 * If jobs are compiled in then this routine expects sigchld to be blocked. 1717 */ 1718 static void 1719 remove_job(Job *j, const char *where) 1720 { 1721 Proc *p, *tmp; 1722 Job **prev, *curr; 1723 1724 mkssert(j != NULL); 1725 prev = &job_list; 1726 curr = job_list; 1727 while (curr && curr != j) { 1728 prev = &curr->next; 1729 curr = *prev; 1730 } 1731 if (curr != j) { 1732 internal_warningf("remove_job: job %s (%s)", "not found", where); 1733 return; 1734 } 1735 *prev = curr->next; 1736 1737 /* free up proc structures */ 1738 for (p = j->proc_list; p != NULL; ) { 1739 tmp = p; 1740 p = p->next; 1741 tmp->next = free_procs; 1742 free_procs = tmp; 1743 } 1744 1745 if ((j->flags & JF_ZOMBIE) && j->ppid == procpid) 1746 --nzombie; 1747 j->next = free_jobs; 1748 free_jobs = j; 1749 1750 if (j == last_job) 1751 last_job = NULL; 1752 if (j == async_job) 1753 async_job = NULL; 1754 } 1755 1756 /* 1757 * put j in a particular location (taking it out job_list if it is there 1758 * already) 1759 * 1760 * If jobs are compiled in then this routine expects sigchld to be blocked. 1761 */ 1762 static void 1763 put_job(Job *j, int where) 1764 { 1765 Job **prev, *curr; 1766 1767 mkssert(j != NULL); 1768 /* Remove job from list (if there) */ 1769 prev = &job_list; 1770 curr = job_list; 1771 while (curr && curr != j) { 1772 prev = &curr->next; 1773 curr = *prev; 1774 } 1775 if (curr == j) 1776 *prev = curr->next; 1777 1778 switch (where) { 1779 case PJ_ON_FRONT: 1780 j->next = job_list; 1781 job_list = j; 1782 break; 1783 1784 case PJ_PAST_STOPPED: 1785 prev = &job_list; 1786 curr = job_list; 1787 for (; curr && curr->state == PSTOPPED; prev = &curr->next, 1788 curr = *prev) 1789 ; 1790 j->next = curr; 1791 *prev = j; 1792 break; 1793 } 1794 } 1795 1796 /* 1797 * nuke a job (called when unable to start full job). 1798 * 1799 * If jobs are compiled in then this routine expects sigchld to be blocked. 1800 */ 1801 static int 1802 kill_job(Job *j, int sig) 1803 { 1804 Proc *p; 1805 int rval = 0; 1806 1807 for (p = j->proc_list; p != NULL; p = p->next) 1808 if (p->pid != 0) 1809 if (kill(p->pid, sig) < 0) 1810 rval = -1; 1811 return (rval); 1812 } 1813 1814 static void 1815 tty_init_talking(void) 1816 { 1817 switch (tty_init_fd()) { 1818 case 0: 1819 break; 1820 case 1: 1821 #ifndef MKSH_DISABLE_TTY_WARNING 1822 warningf(false, "%s: %s %s: %s", 1823 "No controlling tty", "open", "/dev/tty", 1824 cstrerror(errno)); 1825 #endif 1826 break; 1827 case 2: 1828 #ifndef MKSH_DISABLE_TTY_WARNING 1829 warningf(false, "%s: %s", "can't find tty fd", cstrerror(errno)); 1830 #endif 1831 break; 1832 case 3: 1833 warningf(false, "%s: %s %s: %s", "j_ttyinit", 1834 "dup of tty fd", "failed", cstrerror(errno)); 1835 break; 1836 case 4: 1837 warningf(false, "%s: %s: %s", "j_ttyinit", 1838 "can't set close-on-exec flag", cstrerror(errno)); 1839 break; 1840 } 1841 } 1842 1843 static void 1844 tty_init_state(void) 1845 { 1846 if (tty_fd >= 0) { 1847 mksh_tcget(tty_fd, &tty_state); 1848 tty_hasstate = true; 1849 } 1850 } 1851