contrib/chg/chg.c
changeset 28086 65d24ca35496
parent 28085 c0d1bf1b26b7
child 28167 66f6dad20c19
--- a/contrib/chg/chg.c	Fri Jan 29 22:52:16 2016 +0900
+++ b/contrib/chg/chg.c	Tue Jan 19 22:31:59 2016 +0900
@@ -231,6 +231,38 @@
 	debugmsg("forward signal %d", sig);
 }
 
+static void handlestopsignal(int sig)
+{
+	sigset_t unblockset, oldset;
+	struct sigaction sa, oldsa;
+	if (sigemptyset(&unblockset) < 0)
+		goto error;
+	if (sigaddset(&unblockset, sig) < 0)
+		goto error;
+	memset(&sa, 0, sizeof(sa));
+	sa.sa_handler = SIG_DFL;
+	sa.sa_flags = SA_RESTART;
+	if (sigemptyset(&sa.sa_mask) < 0)
+		goto error;
+
+	forwardsignal(sig);
+	if (raise(sig) < 0)  /* resend to self */
+		goto error;
+	if (sigaction(sig, &sa, &oldsa) < 0)
+		goto error;
+	if (sigprocmask(SIG_UNBLOCK, &unblockset, &oldset) < 0)
+		goto error;
+	/* resent signal will be handled before sigprocmask() returns */
+	if (sigprocmask(SIG_SETMASK, &oldset, NULL) < 0)
+		goto error;
+	if (sigaction(sig, &oldsa, NULL) < 0)
+		goto error;
+	return;
+
+error:
+	abortmsg("failed to handle stop signal (errno = %d)", errno);
+}
+
 static void setupsignalhandler(pid_t pid)
 {
 	if (pid <= 0)
@@ -253,6 +285,17 @@
 	sa.sa_flags |= SA_RESETHAND;
 	if (sigaction(SIGTERM, &sa, NULL) < 0)
 		goto error;
+
+	/* propagate job control requests to worker */
+	sa.sa_handler = forwardsignal;
+	sa.sa_flags = SA_RESTART;
+	if (sigaction(SIGCONT, &sa, NULL) < 0)
+		goto error;
+	sa.sa_handler = handlestopsignal;
+	sa.sa_flags = SA_RESTART;
+	if (sigaction(SIGTSTP, &sa, NULL) < 0)
+		goto error;
+
 	return;
 
 error: