X-Git-Url: http://git.osdn.net/view?a=blobdiff_plain;f=src%2Fjobs.c;fp=src%2Fjobs.c;h=0216a342b192c74180b7bdef278d6ee7552997e5;hb=737fdce098f804459a925438e48dd711c31bbc9e;hp=3277c78a01fd05622c82dfacf2bea05688b3a674;hpb=f9948769fe018acb71d1bed0a8db747d5397691f;p=android-x86%2Fexternal-mksh.git diff --git a/src/jobs.c b/src/jobs.c index 3277c78..0216a34 100644 --- a/src/jobs.c +++ b/src/jobs.c @@ -1,8 +1,8 @@ -/* $OpenBSD: jobs.c,v 1.39 2009/12/13 04:36:48 deraadt Exp $ */ +/* $OpenBSD: jobs.c,v 1.40 2013/09/04 15:49:18 millert Exp $ */ /*- * Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2011, - * 2012, 2013 + * 2012, 2013, 2014 * Thorsten Glaser * * Provided that these terms and disclaimer and all copyright notices @@ -23,7 +23,7 @@ #include "sh.h" -__RCSID("$MirOS: src/bin/mksh/jobs.c,v 1.100 2013/07/26 20:33:23 tg Exp $"); +__RCSID("$MirOS: src/bin/mksh/jobs.c,v 1.104 2014/06/10 22:17:09 tg Exp $"); #if HAVE_KILLPG #define mksh_killpg killpg @@ -225,6 +225,54 @@ proc_errorlevel(Proc *p) } } +#if !defined(MKSH_UNEMPLOYED) && HAVE_GETSID +/* suspend the shell */ +void +j_suspend(void) +{ + struct sigaction sa, osa; + + /* Restore tty and pgrp. */ + if (ttypgrp_ok) { + if (tty_hasstate) + mksh_tcset(tty_fd, &tty_state); + if (restore_ttypgrp >= 0) { + if (tcsetpgrp(tty_fd, restore_ttypgrp) < 0) { + warningf(false, "%s: %s %s: %s", "j_suspend", + "tcsetpgrp", "failed", cstrerror(errno)); + } else if (setpgid(0, restore_ttypgrp) < 0) { + warningf(false, "%s: %s %s: %s", "j_suspend", + "setpgid", "failed", cstrerror(errno)); + } + } + } + + /* Suspend the shell. */ + memset(&sa, 0, sizeof(sa)); + sigemptyset(&sa.sa_mask); + sa.sa_handler = SIG_DFL; + sigaction(SIGTSTP, &sa, &osa); + kill(0, SIGTSTP); + + /* Back from suspend, reset signals, pgrp and tty. */ + sigaction(SIGTSTP, &osa, NULL); + if (ttypgrp_ok) { + if (restore_ttypgrp >= 0) { + if (setpgid(0, kshpid) < 0) { + warningf(false, "%s: %s %s: %s", "j_suspend", + "setpgid", "failed", cstrerror(errno)); + ttypgrp_ok = false; + } else if (tcsetpgrp(tty_fd, kshpid) < 0) { + warningf(false, "%s: %s %s: %s", "j_suspend", + "tcsetpgrp", "failed", cstrerror(errno)); + ttypgrp_ok = false; + } + } + tty_init_state(); + } +} +#endif + /* job cleanup before shell exit */ void j_exit(void) @@ -1222,6 +1270,15 @@ j_waitj(Job *j, rv = vp->val.i; p = p->next; } + } else if (Flag(FPIPEFAIL) && (j->proc_list != NULL)) { + Proc *p = j->proc_list; + int i; + + while (p != NULL) { + if ((i = proc_errorlevel(p))) + rv = i; + p = p->next; + } } if (!(flags & JW_ASYNCNOTIFY) @@ -1281,7 +1338,11 @@ j_sigchld(int sig MKSH_A_UNUSED) getrusage(RUSAGE_CHILDREN, &ru0); do { #ifndef MKSH_NOPROSPECTOFWORK - pid = waitpid(-1, &status, (WNOHANG|WUNTRACED)); + pid = waitpid(-1, &status, (WNOHANG | +#ifdef WCONTINUED + WCONTINUED | +#endif + WUNTRACED)); #else pid = wait(&status); #endif @@ -1320,6 +1381,13 @@ j_sigchld(int sig MKSH_A_UNUSED) if (WIFSTOPPED(status)) p->state = PSTOPPED; else +#ifdef WIFCONTINUED + if (WIFCONTINUED(status)) { + p->state = j->state = PRUNNING; + /* skip check_job(), no-op in this case */ + continue; + } else +#endif #endif if (WIFSIGNALED(status)) p->state = PSIGNALLED;