--- a/contrib/chg/chg.c Mon Jul 18 23:31:51 2016 -0500
+++ b/contrib/chg/chg.c Sun Jul 17 22:55:47 2016 +0100
@@ -339,6 +339,7 @@
}
static pid_t pagerpid = 0;
+static pid_t peerpgid = 0;
static pid_t peerpid = 0;
static void forwardsignal(int sig)
@@ -349,6 +350,15 @@
debugmsg("forward signal %d", sig);
}
+static void forwardsignaltogroup(int sig)
+{
+ /* prefer kill(-pgid, sig), fallback to pid if pgid is invalid */
+ pid_t killpid = peerpgid > 1 ? -peerpgid : peerpid;
+ if (kill(killpid, sig) < 0)
+ abortmsgerrno("cannot kill %d", killpid);
+ debugmsg("forward signal %d to %d", sig, killpid);
+}
+
static void handlestopsignal(int sig)
{
sigset_t unblockset, oldset;
@@ -392,15 +402,19 @@
kill(peerpid, SIGPIPE);
}
-static void setupsignalhandler(pid_t pid)
+static void setupsignalhandler(const hgclient_t *hgc)
{
+ pid_t pid = hgc_peerpid(hgc);
if (pid <= 0)
return;
peerpid = pid;
+ pid_t pgid = hgc_peerpgid(hgc);
+ peerpgid = (pgid <= 1 ? 0 : pgid);
+
struct sigaction sa;
memset(&sa, 0, sizeof(sa));
- sa.sa_handler = forwardsignal;
+ sa.sa_handler = forwardsignaltogroup;
sa.sa_flags = SA_RESTART;
if (sigemptyset(&sa.sa_mask) < 0)
goto error;
@@ -411,6 +425,7 @@
goto error;
/* terminate frontend by double SIGTERM in case of server freeze */
+ sa.sa_handler = forwardsignal;
sa.sa_flags |= SA_RESETHAND;
if (sigaction(SIGTERM, &sa, NULL) < 0)
goto error;
@@ -656,7 +671,7 @@
gethgcmd());
}
- setupsignalhandler(hgc_peerpid(hgc));
+ setupsignalhandler(hgc);
pagerpid = setuppager(hgc, argv + 1, argc - 1);
int exitcode = hgc_runcommand(hgc, argv + 1, argc - 1);
restoresignalhandler();