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