##// END OF EJS Templates
localrepo: introduce a `_refreshchangelog` method...
localrepo: introduce a `_refreshchangelog` method See next changeset for usage and documentation for details.

File last commit:

r41367:763b45bc default
r42710:3472a3f9 stable
Show More
sighandlers.c
175 lines | 3.7 KiB | text/x-c | CLexer
Yuya Nishihara
rust-chg: extract signal handlers from chg/procutil.c...
r40154 /*
* 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;
Augie Fackler
cleanup: use clang-tidy to add missing {} around one-line statements...
r41367 if (sigemptyset(&unblockset) < 0) {
Yuya Nishihara
rust-chg: extract signal handlers from chg/procutil.c...
r40154 return;
Augie Fackler
cleanup: use clang-tidy to add missing {} around one-line statements...
r41367 }
if (sigaddset(&unblockset, sig) < 0) {
Yuya Nishihara
rust-chg: extract signal handlers from chg/procutil.c...
r40154 return;
Augie Fackler
cleanup: use clang-tidy to add missing {} around one-line statements...
r41367 }
Yuya Nishihara
rust-chg: extract signal handlers from chg/procutil.c...
r40154 memset(&sa, 0, sizeof(sa));
sa.sa_handler = SIG_DFL;
sa.sa_flags = SA_RESTART;
Augie Fackler
cleanup: use clang-tidy to add missing {} around one-line statements...
r41367 if (sigemptyset(&sa.sa_mask) < 0) {
Yuya Nishihara
rust-chg: extract signal handlers from chg/procutil.c...
r40154 return;
Augie Fackler
cleanup: use clang-tidy to add missing {} around one-line statements...
r41367 }
Yuya Nishihara
rust-chg: extract signal handlers from chg/procutil.c...
r40154
forwardsignal(sig);
Augie Fackler
cleanup: use clang-tidy to add missing {} around one-line statements...
r41367 if (raise(sig) < 0) { /* resend to self */
Yuya Nishihara
rust-chg: extract signal handlers from chg/procutil.c...
r40154 return;
Augie Fackler
cleanup: use clang-tidy to add missing {} around one-line statements...
r41367 }
if (sigaction(sig, &sa, &oldsa) < 0) {
Yuya Nishihara
rust-chg: extract signal handlers from chg/procutil.c...
r40154 return;
Augie Fackler
cleanup: use clang-tidy to add missing {} around one-line statements...
r41367 }
if (sigprocmask(SIG_UNBLOCK, &unblockset, &oldset) < 0) {
Yuya Nishihara
rust-chg: extract signal handlers from chg/procutil.c...
r40154 return;
Augie Fackler
cleanup: use clang-tidy to add missing {} around one-line statements...
r41367 }
Yuya Nishihara
rust-chg: extract signal handlers from chg/procutil.c...
r40154 /* resent signal will be handled before sigprocmask() returns */
Augie Fackler
cleanup: use clang-tidy to add missing {} around one-line statements...
r41367 if (sigprocmask(SIG_SETMASK, &oldset, NULL) < 0) {
Yuya Nishihara
rust-chg: extract signal handlers from chg/procutil.c...
r40154 return;
Augie Fackler
cleanup: use clang-tidy to add missing {} around one-line statements...
r41367 }
if (sigaction(sig, &oldsa, NULL) < 0) {
Yuya Nishihara
rust-chg: extract signal handlers from chg/procutil.c...
r40154 return;
Augie Fackler
cleanup: use clang-tidy to add missing {} around one-line statements...
r41367 }
Yuya Nishihara
rust-chg: extract signal handlers from chg/procutil.c...
r40154 }
/*
* 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;
Augie Fackler
cleanup: use clang-tidy to add missing {} around one-line statements...
r41367 if (sigemptyset(&sa.sa_mask) < 0) {
return -1;
}
if (sigaction(SIGHUP, &sa, NULL) < 0) {
Yuya Nishihara
rust-chg: extract signal handlers from chg/procutil.c...
r40154 return -1;
Augie Fackler
cleanup: use clang-tidy to add missing {} around one-line statements...
r41367 }
if (sigaction(SIGINT, &sa, NULL) < 0) {
Yuya Nishihara
rust-chg: extract signal handlers from chg/procutil.c...
r40154 return -1;
Augie Fackler
cleanup: use clang-tidy to add missing {} around one-line statements...
r41367 }
Yuya Nishihara
rust-chg: extract signal handlers from chg/procutil.c...
r40154
/* terminate frontend by double SIGTERM in case of server freeze */
sa.sa_handler = forwardsignal;
sa.sa_flags |= SA_RESETHAND;
Augie Fackler
cleanup: use clang-tidy to add missing {} around one-line statements...
r41367 if (sigaction(SIGTERM, &sa, NULL) < 0) {
Yuya Nishihara
rust-chg: extract signal handlers from chg/procutil.c...
r40154 return -1;
Augie Fackler
cleanup: use clang-tidy to add missing {} around one-line statements...
r41367 }
Yuya Nishihara
rust-chg: extract signal handlers from chg/procutil.c...
r40154
/* notify the worker about window resize events */
sa.sa_flags = SA_RESTART;
Augie Fackler
cleanup: use clang-tidy to add missing {} around one-line statements...
r41367 if (sigaction(SIGWINCH, &sa, NULL) < 0) {
Yuya Nishihara
rust-chg: extract signal handlers from chg/procutil.c...
r40154 return -1;
Augie Fackler
cleanup: use clang-tidy to add missing {} around one-line statements...
r41367 }
Yuya Nishihara
rust-chg: extract signal handlers from chg/procutil.c...
r40154 /* forward user-defined signals */
Augie Fackler
cleanup: use clang-tidy to add missing {} around one-line statements...
r41367 if (sigaction(SIGUSR1, &sa, NULL) < 0) {
Yuya Nishihara
rust-chg: extract signal handlers from chg/procutil.c...
r40154 return -1;
Augie Fackler
cleanup: use clang-tidy to add missing {} around one-line statements...
r41367 }
if (sigaction(SIGUSR2, &sa, NULL) < 0) {
Yuya Nishihara
rust-chg: extract signal handlers from chg/procutil.c...
r40154 return -1;
Augie Fackler
cleanup: use clang-tidy to add missing {} around one-line statements...
r41367 }
Yuya Nishihara
rust-chg: extract signal handlers from chg/procutil.c...
r40154 /* propagate job control requests to worker */
sa.sa_handler = forwardsignal;
sa.sa_flags = SA_RESTART;
Augie Fackler
cleanup: use clang-tidy to add missing {} around one-line statements...
r41367 if (sigaction(SIGCONT, &sa, NULL) < 0) {
Yuya Nishihara
rust-chg: extract signal handlers from chg/procutil.c...
r40154 return -1;
Augie Fackler
cleanup: use clang-tidy to add missing {} around one-line statements...
r41367 }
Yuya Nishihara
rust-chg: extract signal handlers from chg/procutil.c...
r40154 sa.sa_handler = handlestopsignal;
sa.sa_flags = SA_RESTART;
Augie Fackler
cleanup: use clang-tidy to add missing {} around one-line statements...
r41367 if (sigaction(SIGTSTP, &sa, NULL) < 0) {
Yuya Nishihara
rust-chg: extract signal handlers from chg/procutil.c...
r40154 return -1;
Augie Fackler
cleanup: use clang-tidy to add missing {} around one-line statements...
r41367 }
Yuya Nishihara
rust-chg: extract signal handlers from chg/procutil.c...
r40154
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;
Augie Fackler
cleanup: use clang-tidy to add missing {} around one-line statements...
r41367 if (sigemptyset(&sa.sa_mask) < 0) {
Yuya Nishihara
rust-chg: extract signal handlers from chg/procutil.c...
r40154 return -1;
Augie Fackler
cleanup: use clang-tidy to add missing {} around one-line statements...
r41367 }
Yuya Nishihara
rust-chg: extract signal handlers from chg/procutil.c...
r40154
Augie Fackler
cleanup: use clang-tidy to add missing {} around one-line statements...
r41367 if (sigaction(SIGHUP, &sa, NULL) < 0) {
Yuya Nishihara
rust-chg: extract signal handlers from chg/procutil.c...
r40154 return -1;
Augie Fackler
cleanup: use clang-tidy to add missing {} around one-line statements...
r41367 }
if (sigaction(SIGTERM, &sa, NULL) < 0) {
Yuya Nishihara
rust-chg: extract signal handlers from chg/procutil.c...
r40154 return -1;
Augie Fackler
cleanup: use clang-tidy to add missing {} around one-line statements...
r41367 }
if (sigaction(SIGWINCH, &sa, NULL) < 0) {
Yuya Nishihara
rust-chg: extract signal handlers from chg/procutil.c...
r40154 return -1;
Augie Fackler
cleanup: use clang-tidy to add missing {} around one-line statements...
r41367 }
if (sigaction(SIGCONT, &sa, NULL) < 0) {
Yuya Nishihara
rust-chg: extract signal handlers from chg/procutil.c...
r40154 return -1;
Augie Fackler
cleanup: use clang-tidy to add missing {} around one-line statements...
r41367 }
if (sigaction(SIGTSTP, &sa, NULL) < 0) {
Yuya Nishihara
rust-chg: extract signal handlers from chg/procutil.c...
r40154 return -1;
Augie Fackler
cleanup: use clang-tidy to add missing {} around one-line statements...
r41367 }
Yuya Nishihara
rust-chg: extract signal handlers from chg/procutil.c...
r40154
/* ignore Ctrl+C while shutting down to make pager exits cleanly */
sa.sa_handler = SIG_IGN;
Augie Fackler
cleanup: use clang-tidy to add missing {} around one-line statements...
r41367 if (sigaction(SIGINT, &sa, NULL) < 0) {
Yuya Nishihara
rust-chg: extract signal handlers from chg/procutil.c...
r40154 return -1;
Augie Fackler
cleanup: use clang-tidy to add missing {} around one-line statements...
r41367 }
Yuya Nishihara
rust-chg: extract signal handlers from chg/procutil.c...
r40154
peerpid = 0;
return 0;
}