[PATCH 3 of 3] chg: forward SIGINT, SIGHUP to process group
Jun Wu
quark at fb.com
Sun Jul 17 18:09:43 EDT 2016
# HG changeset patch
# User Jun Wu <quark at fb.com>
# Date 1468792547 -3600
# Sun Jul 17 22:55:47 2016 +0100
# Node ID a655c2315828c82ef6ca33cbde254031a3ca89e2
# Parent 57234c11a5d542865e7360b7b943793e4fd110f7
# Available At https://bitbucket.org/quark-zju/hg-draft
# hg pull https://bitbucket.org/quark-zju/hg-draft -r a655c2315828
chg: forward SIGINT, SIGHUP to process group
These signals are meant to send to a process group, instead of a single
process.
This will allow us to properly kill processes started by the forked server
process, like a ssh process. The behavior difference can be observed by
setting SSH_ASKPASS to a dummy script doing "sleep 100" and then run
"chg push ssh://dest-need-password-auth". Before this patch, the first Ctrl+C
will kill the hg process while ssh-askpass and ssh will remain alive. This
patch will make sure they are killed properly.
diff --git a/contrib/chg/chg.c b/contrib/chg/chg.c
--- a/contrib/chg/chg.c
+++ b/contrib/chg/chg.c
@@ -339,6 +339,7 @@ static void killcmdserver(const struct c
}
static pid_t pagerpid = 0;
+static pid_t peerpgid = 0;
static pid_t peerpid = 0;
static void forwardsignal(int sig)
@@ -349,6 +350,15 @@ static void forwardsignal(int sig)
debugmsg("forward signal %d", sig);
}
+static void forwardsignaltogroup(int sig)
+{
+ /* prefer kill(-pgid, sig) but use pid if pgid is unavailable */
+ pid_t killpid = peerpgid ? -peerpgid : peerpid;
+ if (kill(killpid, sig) < 0)
+ abortmsgerrno("cannot kill %d", killpid);
+ debugmsg("forward signal %d to %d", sig, killpid);
+}
+
static void handlestopsignal(int sig)
{
sigset_t unblockset, oldset;
@@ -392,15 +402,16 @@ static void handlechildsignal(int sig UN
kill(peerpid, SIGPIPE);
}
-static void setupsignalhandler(pid_t pid)
+static void setupsignalhandler(const hgclient_t *hgc)
{
- if (pid <= 0)
+ peerpgid = hgc_peerpgid(hgc);
+ peerpid = hgc_peerpid(hgc);
+ if (peerpgid <= 0 && peerpid <= 0)
return;
- peerpid = pid;
struct sigaction sa;
memset(&sa, 0, sizeof(sa));
- sa.sa_handler = forwardsignal;
+ sa.sa_handler = forwardsignaltogroup;
sa.sa_flags = SA_RESTART;
if (sigemptyset(&sa.sa_mask) < 0)
goto error;
@@ -411,6 +422,7 @@ static void setupsignalhandler(pid_t pid
goto error;
/* terminate frontend by double SIGTERM in case of server freeze */
+ sa.sa_handler = forwardsignal;
sa.sa_flags |= SA_RESETHAND;
if (sigaction(SIGTERM, &sa, NULL) < 0)
goto error;
@@ -656,7 +668,7 @@ int main(int argc, const char *argv[], c
gethgcmd());
}
- setupsignalhandler(hgc_peerpid(hgc));
+ setupsignalhandler(hgc);
pagerpid = setuppager(hgc, argv + 1, argc - 1);
int exitcode = hgc_runcommand(hgc, argv + 1, argc - 1);
restoresignalhandler();
More information about the Mercurial-devel
mailing list