(patch at the end)
this happens when ksh isn't the process group leader
not being the group leader happens when, e.g., started as a background process
in a non interactive shell or being a rhs member of a pipe:
$ /bin/sh <<'.'
/bin/sh -c 'ps -opid,pgid -p$$' &
.
PID PGID
5784 6401
$ : | /bin/sh -c 'ps -opid,pgid -p$$'
PID PGID
12208 20586
compile:
/* t.c BOF */
#include <sys/types.h>
#include <sys/wait.h>
#include <err.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int
main(int argc, char **argv)
{
int gflag, s;
char c;
gflag = 0;
while ((c = getopt(argc, argv, "g")) != -1)
if (c == 'g')
gflag = 1;
else
exit(2);
argc -= optind;
argv += optind;
if (argc < 1)
errx(2, "invalid arguments");
switch (fork()) {
case 0:
if (gflag)
setpgid(0, 0);
execv(*argv, argv);
err(3, "exec: %s", *argv);
case -1:
err(3, "fork");
}
if (wait(&s) == -1)
err(3, "wait");
printf("eb=%d en=%d sb=%d sn=%d\n", WIFEXITED(s), WEXITSTATUS(s),
WIFSIGNALED(s), WTERMSIG(s));
exit(0);
}
/* t.c EOF */
all lines should produce the same output, but don't because of the bug:
$ {
./t /bin/ksh -c 'kill -INT $$'
./t -g /bin/ksh -c 'kill -INT $$'
} | column -t
eb=1 en=130 sb=0 sn=0
eb=0 en=0 sb=1 sn=2
patch:
Index: main.c
===================================================================
RCS file: /cvs/src/bin/ksh/main.c,v
retrieving revision 1.47
diff -p -u -r1.47 main.c
--- main.c 7 Sep 2011 11:33:25 -0000 1.47
+++ main.c 10 Nov 2011 06:25:01 -0000
@@ -666,11 +666,11 @@ quitenv(struct shf *shf)
* Don't do it for SIGQUIT, since we'd
* dump a core..
*/
- if ((sig == SIGINT || sig == SIGTERM) &&
- getpgrp() == kshpid) {
+ if (sig == SIGINT || sig == SIGTERM) {
setsig(&sigtraps[sig], SIG_DFL,
SS_RESTORE_CURR|SS_FORCE);
- kill(0, sig);
+ kill((getpgrp() == kshpid)
+ ? 0 : kshpid, sig);
}
}
}