diff -r 247ea0dfdb94 -r cf99de051385 contrib/chg/chg.c --- 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);