Mercurial > hg
view rust/chg/src/sighandlers.c @ 41692:ee7b7bd432a1
rust: translated random test of missingancestors
This is a Rust implementation of the random
DAG generator and related incrementalmissingancestors
tests against a naive brute force implementation.
It is provided as an integration test, so that it
won't run by default if any unit test fails.
In case of a failed example, all needed information
for reproduction is included in the panic message,
(this is how
`test_remove_ancestors_from_case1()` has been generated),
as well as the random seed.
The whole test is rerunnable by passing the random seed
in the TEST_RANDOM_SEED environment variable.
The other parameters (numbers of iterations) can be passed
in the TEST_MISSING_ANCESTORS environment variable.
An alternative would have been to expose to Python
MissingAncestors<VecGraphs> but that would have meant
pollution of the release build used from Python,
whereas we do it in this changeset within the tests submodule
Differential Revision: https://phab.mercurial-scm.org/D5417
author | Georges Racinet <gracinet@anybox.fr> |
---|---|
date | Sun, 02 Dec 2018 16:19:22 +0100 |
parents | 763b45bc4483 |
children |
line wrap: on
line source
/* * Signal handlers for cHg * * Copyright 2011, 2018 Yuya Nishihara <yuya@tcha.org> * * This software may be used and distributed according to the terms of the * GNU General Public License version 2 or any later version. */ #include <assert.h> #include <errno.h> #include <signal.h> #include <string.h> #include <unistd.h> static pid_t peerpgid = 0; static pid_t peerpid = 0; static void forwardsignal(int sig) { assert(peerpid > 0); (void)kill(peerpid, sig); } static void forwardsignaltogroup(int sig) { /* prefer kill(-pgid, sig), fallback to pid if pgid is invalid */ pid_t killpid = peerpgid > 1 ? -peerpgid : peerpid; (void)kill(killpid, sig); } static void handlestopsignal(int sig) { sigset_t unblockset, oldset; struct sigaction sa, oldsa; if (sigemptyset(&unblockset) < 0) { return; } if (sigaddset(&unblockset, sig) < 0) { return; } memset(&sa, 0, sizeof(sa)); sa.sa_handler = SIG_DFL; sa.sa_flags = SA_RESTART; if (sigemptyset(&sa.sa_mask) < 0) { return; } forwardsignal(sig); if (raise(sig) < 0) { /* resend to self */ return; } if (sigaction(sig, &sa, &oldsa) < 0) { return; } if (sigprocmask(SIG_UNBLOCK, &unblockset, &oldset) < 0) { return; } /* resent signal will be handled before sigprocmask() returns */ if (sigprocmask(SIG_SETMASK, &oldset, NULL) < 0) { return; } if (sigaction(sig, &oldsa, NULL) < 0) { return; } } /* * Installs signal handlers. * * Returns 0 on success, -1 on error and errno is set appropriately. * Installed handlers wouldn't be cleaned up on error. */ int setupsignalhandler(pid_t pid, pid_t pgid) { if (pid <= 0) { errno = EINVAL; return -1; } peerpid = pid; peerpgid = (pgid <= 1 ? 0 : pgid); struct sigaction sa; memset(&sa, 0, sizeof(sa)); /* deadly signals meant to be sent to a process group: * - SIGHUP: usually generated by the kernel, when termination of a * process causes that process group to become orphaned * - SIGINT: usually generated by the terminal */ sa.sa_handler = forwardsignaltogroup; sa.sa_flags = SA_RESTART; if (sigemptyset(&sa.sa_mask) < 0) { return -1; } if (sigaction(SIGHUP, &sa, NULL) < 0) { return -1; } if (sigaction(SIGINT, &sa, NULL) < 0) { return -1; } /* 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) { return -1; } /* notify the worker about window resize events */ sa.sa_flags = SA_RESTART; if (sigaction(SIGWINCH, &sa, NULL) < 0) { return -1; } /* forward user-defined signals */ if (sigaction(SIGUSR1, &sa, NULL) < 0) { return -1; } if (sigaction(SIGUSR2, &sa, NULL) < 0) { return -1; } /* propagate job control requests to worker */ sa.sa_handler = forwardsignal; sa.sa_flags = SA_RESTART; if (sigaction(SIGCONT, &sa, NULL) < 0) { return -1; } sa.sa_handler = handlestopsignal; sa.sa_flags = SA_RESTART; if (sigaction(SIGTSTP, &sa, NULL) < 0) { return -1; } return 0; } /* * Restores signal handlers to the default, and masks SIGINT. * * Returns 0 on success, -1 on error and errno is set appropriately. */ int restoresignalhandler(void) { struct sigaction sa; memset(&sa, 0, sizeof(sa)); sa.sa_handler = SIG_DFL; sa.sa_flags = SA_RESTART; if (sigemptyset(&sa.sa_mask) < 0) { return -1; } if (sigaction(SIGHUP, &sa, NULL) < 0) { return -1; } if (sigaction(SIGTERM, &sa, NULL) < 0) { return -1; } if (sigaction(SIGWINCH, &sa, NULL) < 0) { return -1; } if (sigaction(SIGCONT, &sa, NULL) < 0) { return -1; } if (sigaction(SIGTSTP, &sa, NULL) < 0) { return -1; } /* ignore Ctrl+C while shutting down to make pager exits cleanly */ sa.sa_handler = SIG_IGN; if (sigaction(SIGINT, &sa, NULL) < 0) { return -1; } peerpid = 0; return 0; }