[PATCH 3 of 3] chg: forward job control signals to worker process (issue5051)
Yuya Nishihara
yuya at tcha.org
Thu Feb 11 14:05:13 UTC 2016
# HG changeset patch
# User Yuya Nishihara <yuya at tcha.org>
# Date 1453210319 -32400
# Tue Jan 19 22:31:59 2016 +0900
# Node ID 63251841f5f927f677b90957eec1230017f3a515
# Parent def82508e22c33bdfe042fd372bddf6dc3f93e2c
chg: forward job control signals to worker process (issue5051)
This is necessary to suspend/resume long pulls, interactive curses session,
etc.
The implementation is based on emacsclient, but our version doesn't test if
chg process is foreground or not before propagating SIGCONT. This is because
chg isn't always an interactive session. If we copy the SIGTTIN/SIGTTOU
emulation from emacsclient, non-interactive session can't be moved to a
background job.
$ chg pull
^Z
suspended
$ bg %1
[1] continued
[1] suspended (tty input) # wrong
https://github.com/emacs-mirror/emacs/blob/0e96320/lib-src/emacsclient.c#L1094
diff --git a/contrib/chg/chg.c b/contrib/chg/chg.c
--- a/contrib/chg/chg.c
+++ b/contrib/chg/chg.c
@@ -231,6 +231,38 @@ static void forwardsignal(int sig)
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 @@ static void setupsignalhandler(pid_t pid
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:
More information about the Mercurial-devel
mailing list