diff options
-rw-r--r-- | bin/sh/arith.y | 9 | ||||
-rw-r--r-- | bin/sh/arith_lex.l | 6 | ||||
-rw-r--r-- | bin/sh/error.c | 41 | ||||
-rw-r--r-- | bin/sh/error.h | 7 | ||||
-rw-r--r-- | bin/sh/jobs.c | 35 | ||||
-rw-r--r-- | bin/sh/jobs.h | 5 | ||||
-rw-r--r-- | bin/sh/miscbltin.c | 3 | ||||
-rw-r--r-- | bin/sh/trap.c | 28 | ||||
-rw-r--r-- | bin/sh/trap.h | 3 |
9 files changed, 92 insertions, 45 deletions
diff --git a/bin/sh/arith.y b/bin/sh/arith.y index 49ca474..87f2f45 100644 --- a/bin/sh/arith.y +++ b/bin/sh/arith.y @@ -88,12 +88,12 @@ expr: ARITH_LPAREN expr ARITH_RPAREN = { $$ = $2; } * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: arith.y,v 1.6 1997/02/22 13:58:21 peter Exp $ + * $Id: arith.y,v 1.7 1998/05/18 06:43:27 charnier Exp $ */ -#ifndef lint +#if 0 static char sccsid[] = "@(#)arith.y 8.3 (Berkeley) 5/4/95"; -#endif /* not lint */ +#endif #include "shell.h" #include "error.h" @@ -103,6 +103,9 @@ static char sccsid[] = "@(#)arith.y 8.3 (Berkeley) 5/4/95"; char *arith_buf, *arith_startbuf; extern void arith_lex_reset(); +int yyparse(void); +int yylex(void); + int arith(s) char *s; diff --git a/bin/sh/arith_lex.l b/bin/sh/arith_lex.l index 6836d80..6c1b171 100644 --- a/bin/sh/arith_lex.l +++ b/bin/sh/arith_lex.l @@ -34,12 +34,12 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: arith_lex.l,v 1.9 1997/02/22 13:58:21 peter Exp $ + * $Id: arith_lex.l,v 1.10 1998/05/18 06:43:28 charnier Exp $ */ -#ifndef lint +#if 0 static char sccsid[] = "@(#)arith_lex.l 8.3 (Berkeley) 5/4/95"; -#endif /* not lint */ +#endif #include <unistd.h> #include "y.tab.h" diff --git a/bin/sh/error.c b/bin/sh/error.c index 9e383e3..0464f6e 100644 --- a/bin/sh/error.c +++ b/bin/sh/error.c @@ -39,7 +39,7 @@ static char sccsid[] = "@(#)error.c 8.2 (Berkeley) 5/4/95"; #endif static const char rcsid[] = - "$Id$"; + "$Id: error.c,v 1.10 1998/05/18 06:43:32 charnier Exp $"; #endif /* not lint */ /* @@ -52,6 +52,7 @@ static const char rcsid[] = #include "output.h" #include "error.h" #include "show.h" +#include "trap.h" #include <signal.h> #include <unistd.h> #include <errno.h> @@ -62,9 +63,9 @@ static const char rcsid[] = */ struct jmploc *handler; -int exception; -volatile int suppressint; -volatile int intpending; +volatile sig_atomic_t exception; +int suppressint; +volatile sig_atomic_t intpending; char *commandname; @@ -90,29 +91,43 @@ exraise(e) /* * Called from trap.c when a SIGINT is received. (If the user specifies * that SIGINT is to be trapped or ignored using the trap builtin, then - * this routine is not called.) Suppressint is nonzero when interrupts - * are held using the INTOFF macro. The call to _exit is necessary because - * there is a short period after a fork before the signal handlers are - * set to the appropriate value for the child. (The test for iflag is - * just defensive programming.) + * this routine is not called.) Supressint is nonzero when interrupts + * are held using the INTOFF macro. If SIGINTs are not suppressed and + * the shell is not a root shell, then we want to be terminated if we + * get here, as if we were terminated directly by a SIGINT. Arrange for + * this here. */ void onint() { sigset_t sigset; - if (suppressint) { + /* The !in_dotrap is save. The only way we can arrive here with + * in_dotrap set is that a trap handler set SIGINT to default + * and killed itself. + */ + + if (suppressint && !in_dotrap) { intpending++; return; } intpending = 0; sigemptyset(&sigset); sigprocmask(SIG_SETMASK, &sigset, NULL); - out2str("\n"); + + /* This doesn't seem to be needed. Note that main emit a newline + * as well. + */ +#if 0 + if (tcgetpgrp(0) == getpid()) + write(STDERR_FILENO, "\n", 1); +#endif if (rootshell && iflag) exraise(EXINT); - else - _exit(128 + SIGINT); + else { + signal(SIGINT, SIG_DFL); + kill(getpid(), SIGINT); + } } diff --git a/bin/sh/error.h b/bin/sh/error.h index bb3eafe..eb0f523 100644 --- a/bin/sh/error.h +++ b/bin/sh/error.h @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * @(#)error.h 8.2 (Berkeley) 5/4/95 - * $Id$ + * $Id: error.h,v 1.7 1997/02/22 13:58:23 peter Exp $ */ /* @@ -57,6 +57,7 @@ */ #include <setjmp.h> +#include <signal.h> struct jmploc { jmp_buf loc; @@ -79,8 +80,8 @@ extern int exception; * more fun than worrying about efficiency and portability. :-)) */ -extern volatile int suppressint; -extern volatile int intpending; +extern volatile sig_atomic_t suppressint; +extern volatile sig_atomic_t intpending; extern char *commandname; /* name of command--printed on error */ #define INTOFF suppressint++ diff --git a/bin/sh/jobs.c b/bin/sh/jobs.c index 2cfb4c3..4b5694a 100644 --- a/bin/sh/jobs.c +++ b/bin/sh/jobs.c @@ -39,7 +39,7 @@ static char sccsid[] = "@(#)jobs.c 8.5 (Berkeley) 5/4/95"; #endif static const char rcsid[] = - "$Id$"; + "$Id: jobs.c,v 1.20 1998/05/18 06:43:47 charnier Exp $"; #endif /* not lint */ #include <fcntl.h> @@ -87,6 +87,8 @@ MKINIT pid_t backgndpid = -1; /* pid of last background process */ int initialpgrp; /* pgrp of shell on invocation */ int curjob; /* current job */ #endif +int in_waitcmd = 0; /* Are we in waitcmd? */ +volatile sig_atomic_t breakwaitcmd = 0; /* Should wait be terminated? */ #if JOBS STATIC void restartjob __P((struct job *)); @@ -95,7 +97,7 @@ STATIC void freejob __P((struct job *)); STATIC struct job *getjob __P((char *)); STATIC int dowait __P((int, struct job *)); #if SYSV -STATIC int onsigchild __P((void)); +STATIC volatile int onsigchild __P((void)); #endif STATIC int waitproc __P((int, int *)); STATIC void cmdtxt __P((union node *)); @@ -385,7 +387,10 @@ waitcmd(argc, argv) } else { job = NULL; } - for (;;) { /* loop until process terminated or stopped */ + in_waitcmd++; + do { /* loop until process terminated or stopped or SIGINT is + * received + */ if (job != NULL) { if (job->state) { status = job->ps[job->nprocs - 1].status; @@ -410,8 +415,11 @@ waitcmd(argc, argv) break; } } - dowait(1, (struct job *)NULL); - } + } while (dowait(1, (struct job *)NULL) != -1); + in_waitcmd--; + + /* Not reachable */ + return 0; } @@ -727,9 +735,12 @@ waitforjob(jp) st = WTERMSIG(status) + 128; if (! JOBS || jp->state == JOBDONE) freejob(jp); - CLEAR_PENDING_INT; - if (WIFSIGNALED(status) && WTERMSIG(status) == SIGINT) - kill(getpid(), SIGINT); + if (int_pending()) { + if (WIFSIGNALED(status) && WTERMSIG(status) == SIGINT) + kill(getpid(), SIGINT); + else + CLEAR_PENDING_INT; + } INTON; return st; } @@ -759,7 +770,11 @@ dowait(block, job) do { pid = waitproc(block, &status); TRACE(("wait returns %d, status=%d\n", pid, status)); - } while (pid == -1 && errno == EINTR); + } while (pid == -1 && errno == EINTR && breakwaitcmd == 0); + if (breakwaitcmd != 0) { + breakwaitcmd = 0; + return -1; + } if (pid <= 0) return pid; INTOFF; @@ -867,7 +882,7 @@ dowait(block, job) */ #ifdef SYSV -STATIC int gotsigchild; +STATIC sig_atomic_t gotsigchild; STATIC int onsigchild() { gotsigchild = 1; diff --git a/bin/sh/jobs.h b/bin/sh/jobs.h index 6e5859d..3182a65 100644 --- a/bin/sh/jobs.h +++ b/bin/sh/jobs.h @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * @(#)jobs.h 8.2 (Berkeley) 5/4/95 - * $Id: jobs.h,v 1.5 1997/02/22 13:58:29 peter Exp $ + * $Id: jobs.h,v 1.6 1997/08/18 02:53:20 steve Exp $ */ /* Mode argument to forkshell. Don't change FORK_FG or FORK_BG. */ @@ -42,6 +42,7 @@ #define FORK_BG 1 #define FORK_NOJOB 2 +#include <signal.h> /* For sig_atomic_t */ /* * A job structure contains information about a job. A job is either a @@ -77,6 +78,8 @@ struct job { extern pid_t backgndpid; /* pid of last background process */ extern int job_warning; /* user was warned about stopped jobs */ +extern int in_waitcmd; /* Are we in wait? */ +extern volatile sig_atomic_t breakwaitcmd; /* Should wait be terminated? */ void setjobctl __P((int)); int fgcmd __P((int, char **)); diff --git a/bin/sh/miscbltin.c b/bin/sh/miscbltin.c index 85d1091..cde9e5d 100644 --- a/bin/sh/miscbltin.c +++ b/bin/sh/miscbltin.c @@ -39,13 +39,14 @@ static char sccsid[] = "@(#)miscbltin.c 8.4 (Berkeley) 5/4/95"; #endif static const char rcsid[] = - "$Id$"; + "$Id: miscbltin.c,v 1.15 1998/05/18 06:43:58 charnier Exp $"; #endif /* not lint */ /* * Miscelaneous builtins. */ +#include <stdlib.h> /* strtol() */ #include <sys/types.h> #include <sys/stat.h> #include <sys/time.h> diff --git a/bin/sh/trap.c b/bin/sh/trap.c index b21928f..c3ab48a 100644 --- a/bin/sh/trap.c +++ b/bin/sh/trap.c @@ -39,7 +39,7 @@ static char sccsid[] = "@(#)trap.c 8.5 (Berkeley) 6/5/95"; #endif static const char rcsid[] = - "$Id$"; + "$Id: trap.c,v 1.11 1998/05/18 06:44:22 charnier Exp $"; #endif /* not lint */ #include <signal.h> @@ -75,9 +75,11 @@ static const char rcsid[] = MKINIT char sigmode[NSIG]; /* current value of signal */ -int pendingsigs; /* indicates some signal received */ +int pendingsigs; /* indicates some signal received */ +int in_dotrap = 0; /* Do we execute in a trap handler? */ static char *trap[NSIG]; /* trap handler commands */ -static char gotsig[NSIG]; /* indicates specified signal received */ +static volatile sig_atomic_t gotsig[NSIG]; + /* indicates specified signal received */ static int ignore_sigchld; /* Used while handling SIGCHLD traps. */ static int getsigaction __P((int, sig_t *)); @@ -221,11 +223,10 @@ setsignal(signo) action = S_CATCH; else action = S_IGN; - if (rootshell && action == S_DFL) { + if (action == S_DFL) { switch (signo) { case SIGINT: - if (iflag) - action = S_CATCH; + action = S_CATCH; break; case SIGQUIT: #ifdef DEBUG @@ -236,15 +237,16 @@ setsignal(signo) break; } #endif - /* FALLTHROUGH */ + action = S_IGN; + break; case SIGTERM: - if (iflag) + if (rootshell && iflag) action = S_IGN; break; #if JOBS case SIGTSTP: case SIGTTOU: - if (mflag) + if (rootshell && mflag) action = S_IGN; break; #endif @@ -356,6 +358,10 @@ onsig(signo) if (signo != SIGCHLD || !ignore_sigchld) gotsig[signo] = 1; pendingsigs++; + if (signo == SIGINT && in_waitcmd != 0) { + dotrap(); + breakwaitcmd = 1; + } } @@ -369,6 +375,7 @@ dotrap() int i; int savestatus; + in_dotrap++; for (;;) { for (i = 1; i < NSIG; i++) { if (gotsig[i]) { @@ -392,6 +399,7 @@ dotrap() if (i >= NSIG) break; } + in_dotrap--; pendingsigs = 0; } @@ -403,7 +411,7 @@ void setinteractive(on) int on; { - static int is_interactive = 0; + static int is_interactive = -1; if (on == is_interactive) return; diff --git a/bin/sh/trap.h b/bin/sh/trap.h index a042a16..132b6ee 100644 --- a/bin/sh/trap.h +++ b/bin/sh/trap.h @@ -34,10 +34,11 @@ * SUCH DAMAGE. * * @(#)trap.h 8.3 (Berkeley) 6/5/95 - * $Id: trap.h,v 1.6 1997/02/22 13:58:47 peter Exp $ + * $Id: trap.h,v 1.7 1997/11/10 11:32:24 bde Exp $ */ extern int pendingsigs; +extern int in_dotrap; int trapcmd __P((int, char **)); void clear_traps __P((void)); |