contrib/chg/chg.c
branchstable
changeset 29608 681fe090d82e
parent 29440 009cc6c89d0f
child 30513 ff7df4bb75de
--- 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();