contrib/chg/chg.c
changeset 29429 cf99de051385
parent 29370 3ddf4d0c4170
child 29440 009cc6c89d0f
--- a/contrib/chg/chg.c	Fri Jun 24 17:06:41 2016 +0100
+++ b/contrib/chg/chg.c	Fri Jun 24 15:21:10 2016 +0100
@@ -338,6 +338,7 @@
 	}
 }
 
+static pid_t pagerpid = 0;
 static pid_t peerpid = 0;
 
 static void forwardsignal(int sig)
@@ -380,6 +381,17 @@
 	abortmsgerrno("failed to handle stop signal");
 }
 
+static void handlechildsignal(int sig)
+{
+	if (peerpid == 0 || pagerpid == 0)
+		return;
+	/* if pager exits, notify the server with SIGPIPE immediately.
+	 * otherwise the server won't get SIGPIPE if it does not write
+	 * anything. (issue5278) */
+	if (waitpid(pagerpid, NULL, WNOHANG) == pagerpid)
+		kill(peerpid, SIGPIPE);
+}
+
 static void setupsignalhandler(pid_t pid)
 {
 	if (pid <= 0)
@@ -416,6 +428,11 @@
 	sa.sa_flags = SA_RESTART;
 	if (sigaction(SIGTSTP, &sa, NULL) < 0)
 		goto error;
+	/* get notified when pager exits */
+	sa.sa_handler = handlechildsignal;
+	sa.sa_flags = SA_RESTART;
+	if (sigaction(SIGCHLD, &sa, NULL) < 0)
+		goto error;
 
 	return;
 
@@ -442,6 +459,8 @@
 		goto error;
 	if (sigaction(SIGTSTP, &sa, NULL) < 0)
 		goto error;
+	if (sigaction(SIGCHLD, &sa, NULL) < 0)
+		goto error;
 
 	/* ignore Ctrl+C while shutting down to make pager exits cleanly */
 	sa.sa_handler = SIG_IGN;
@@ -638,7 +657,7 @@
 	}
 
 	setupsignalhandler(hgc_peerpid(hgc));
-	pid_t pagerpid = setuppager(hgc, argv + 1, argc - 1);
+	pagerpid = setuppager(hgc, argv + 1, argc - 1);
 	int exitcode = hgc_runcommand(hgc, argv + 1, argc - 1);
 	restoresignalhandler();
 	hgc_close(hgc);