chg: reset signal handlers to default before waiting pager
authorYuya Nishihara <yuya@tcha.org>
Wed, 15 Jun 2016 23:32:00 +0900
changeset 29369 85a18f3c0bdd
parent 29367 4e6e280e238f
child 29370 3ddf4d0c4170
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.
contrib/chg/chg.c
--- a/contrib/chg/chg.c	Mon Jun 13 05:11:56 2016 +0900
+++ b/contrib/chg/chg.c	Wed Jun 15 23:32:00 2016 +0900
@@ -423,6 +423,35 @@
 	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 @@
 	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)