Patchwork [1,of,2] chg: reset signal handlers to default before waiting pager

login
register
mail settings
Submitter Yuya Nishihara
Date June 15, 2016, 3:17 p.m.
Message ID <3cf2517e5c15dcc0fc9c.1466003828@mimosa>
Download mbox | patch
Permalink /patch/15523/
State Accepted
Headers show

Comments

Yuya Nishihara - June 15, 2016, 3:17 p.m.
# HG changeset patch
# User Yuya Nishihara <yuya@tcha.org>
# Date 1466001120 -32400
#      Wed Jun 15 23:32:00 2016 +0900
# Node ID 3cf2517e5c15dcc0fc9c433350514c3e25e4f737
# Parent  3c4f66dd14659be71eb26ce77da991cb2a1babe8
chg: reset signal handlers to default before waiting pager

Our signal handlers forward signals to the server process, but it will
disappear soon after hgc_close(). So we should unregister handlers before
hgc_close(). Otherwise chg would abort due to kill(perrpid, sig) failure.

The problem is spotted by SIGWINCH while waiting pager termination.

Patch

diff --git a/contrib/chg/chg.c b/contrib/chg/chg.c
--- a/contrib/chg/chg.c
+++ b/contrib/chg/chg.c
@@ -423,6 +423,35 @@  error:
 	abortmsgerrno("failed to set up signal handlers");
 }
 
+static void restoresignalhandler()
+{
+	struct sigaction sa;
+	memset(&sa, 0, sizeof(sa));
+	sa.sa_handler = SIG_DFL;
+	sa.sa_flags = SA_RESTART;
+	if (sigemptyset(&sa.sa_mask) < 0)
+		goto error;
+
+	if (sigaction(SIGHUP, &sa, NULL) < 0)
+		goto error;
+	if (sigaction(SIGINT, &sa, NULL) < 0)
+		goto error;
+	if (sigaction(SIGTERM, &sa, NULL) < 0)
+		goto error;
+	if (sigaction(SIGWINCH, &sa, NULL) < 0)
+		goto error;
+	if (sigaction(SIGCONT, &sa, NULL) < 0)
+		goto error;
+	if (sigaction(SIGTSTP, &sa, NULL) < 0)
+		goto error;
+
+	peerpid = 0;
+	return;
+
+error:
+	abortmsgerrno("failed to restore signal handlers");
+}
+
 /* This implementation is based on hgext/pager.py (post 369741ef7253)
  * Return 0 if pager is not started, or pid of the pager */
 static pid_t setuppager(hgclient_t *hgc, const char *const args[],
@@ -608,6 +637,7 @@  int main(int argc, const char *argv[], c
 	setupsignalhandler(hgc_peerpid(hgc));
 	pid_t pagerpid = setuppager(hgc, argv + 1, argc - 1);
 	int exitcode = hgc_runcommand(hgc, argv + 1, argc - 1);
+	restoresignalhandler();
 	hgc_close(hgc);
 	freecmdserveropts(&opts);
 	if (pagerpid)