summaryrefslogtreecommitdiffstats
path: root/bin/sh/jobs.c
diff options
context:
space:
mode:
authorcracauer <cracauer@FreeBSD.org>1998-08-24 10:20:37 +0000
committercracauer <cracauer@FreeBSD.org>1998-08-24 10:20:37 +0000
commit8a3c521f04ee9ad807d4c737f050230cb04ce36d (patch)
tree8ccf28d7f10330488ab5bce78116d30f74886c79 /bin/sh/jobs.c
parentf3d290b0b53aa55bf027aba6c54dd0e5b1d101f3 (diff)
downloadFreeBSD-src-8a3c521f04ee9ad807d4c737f050230cb04ce36d.zip
FreeBSD-src-8a3c521f04ee9ad807d4c737f050230cb04ce36d.tar.gz
Do not exit on SIGINT in non-interactive shells, fixes PR 1206,
i.e. this makes emacs usable from system(3). Programs called from shellscripts are now required to exit with proper signal status. That means, they have to kill themself. Exiting with faked numerical exit code is not sufficient. Exit with proper signal status if script exits on signal. Make the wait builtin interruptable, both with and without traps set. Use volatile sig_atomic_t where (and only where) appropriate. (Almost) fix printing of newlines on SIGINT. Make traps setable from trap handlers. This is needed for shellscripts that catch SIGINT for cleanup work but intend to exit on it, hance have to kill themself from a trap handler. I.e. mkdep. While I'm at it, make it -Wall clean. -Wall is not enabled in Makefile, since vararg warnx() macro calls in usr.bin/printf/printf.c are not -Wall-able. PR: 1206 Obtained from: Basic SIGINT fix from Bruce Evans
Diffstat (limited to 'bin/sh/jobs.c')
-rw-r--r--bin/sh/jobs.c35
1 files changed, 25 insertions, 10 deletions
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;
OpenPOWER on IntegriCloud