@@ -67,17 +67,28 @@
#define EXIT(v) { ExitCode = (v); goto Exit; }
static int Interrupted = 0;
+static pid_t Int_From = 0;
-static void SignalHandler(int signum)
+static void SignalHandler(int signum, siginfo_t *si, void *uc)
{
- if (signum != SIGPIPE) {
+ struct sigaction sa;
+ Int_From = si->si_pid;
+ // accept Ctrl-C only from a controlling terminal or shell
+ if (signum == SIGINT) {
+ if (Int_From == 0) {
+ Interrupted = signum;
+ Interface->Interrupt();
+ }
+ } else if (signum != SIGPIPE) {
Interrupted = signum;
Interface->Interrupt();
- }
- signal(signum, SignalHandler);
+ }
+ sa.sa_flags = SA_SIGINFO;
+ sa.sa_sigaction = SignalHandler;
+ sigaction(signum, &sa, NULL);
}
-static void Watchdog(int signum)
+static void Watchdog(int signum, siginfo_t *si, void *uc)
{
// Something terrible must have happened that prevented the 'alarm()' from
// being called in time, so let's get out of here:
@@ -88,7 +99,7 @@
int main(int argc, char *argv[])
{
// Save terminal settings:
-
+ struct sigaction sa, oldsigact;
struct termios savedTm;
bool HasStdin = (tcgetpgrp(STDIN_FILENO) == getpid() || getppid() != (pid_t)1) && tcgetattr(STDIN_FILENO, &savedTm) == 0;
@@ -500,12 +511,65 @@
// Signal handlers:
+/*
if (signal(SIGHUP, SignalHandler) == SIG_IGN) signal(SIGHUP, SIG_IGN);
+*/
+ sa.sa_sigaction = SignalHandler;
+ sa.sa_flags = SA_SIGINFO;
+ sigaction (SIGHUP, &sa, &oldsigact);
+ if (oldsigact.sa_handler == SIG_IGN) {
+ sa.sa_handler = SIG_IGN;
+ sa.sa_flags = 0;
+ sigaction (SIGHUP, &sa, NULL);
+ }
+/*
if (signal(SIGINT, SignalHandler) == SIG_IGN) signal(SIGINT, SIG_IGN);
+*/
+ sa.sa_sigaction = SignalHandler;
+ sa.sa_flags = SA_SIGINFO;
+ sigaction (SIGINT, &sa, &oldsigact);
+ if (oldsigact.sa_handler == SIG_IGN) {
+ sa.sa_handler = SIG_IGN;
+ sa.sa_flags = 0;
+ sigaction (SIGINT, &sa, NULL);
+ }
+/*
if (signal(SIGTERM, SignalHandler) == SIG_IGN) signal(SIGTERM, SIG_IGN);
+*/
+ sa.sa_sigaction = SignalHandler;
+ sa.sa_flags = SA_SIGINFO;
+ sigaction (SIGTERM, &sa, &oldsigact);
+ if (oldsigact.sa_handler == SIG_IGN) {
+ sa.sa_handler = SIG_IGN;
+ sa.sa_flags = 0;
+ sigaction (SIGTERM, &sa, NULL);
+ }
+/*
if (signal(SIGPIPE, SignalHandler) == SIG_IGN) signal(SIGPIPE, SIG_IGN);
+*/
+ sa.sa_sigaction = SignalHandler;
+ sa.sa_flags = SA_SIGINFO;
+ sigaction (SIGPIPE, &sa, &oldsigact);
+ if (oldsigact.sa_handler == SIG_IGN) {
+ sa.sa_handler = SIG_IGN;
+ sa.sa_flags = 0;
+ sigaction (SIGPIPE, &sa, NULL);
+ }
+
if (WatchdogTimeout > 0)
+/*
if (signal(SIGALRM, Watchdog) == SIG_IGN) signal(SIGALRM, SIG_IGN);
+*/
+ {
+ sa.sa_sigaction = Watchdog;
+ sa.sa_flags = SA_SIGINFO;
+ sigaction (SIGALRM, &sa, &oldsigact);
+ if (oldsigact.sa_handler == SIG_IGN) {
+ sa.sa_handler = SIG_IGN;
+ sa.sa_flags = 0;
+ sigaction (SIGALRM, &sa, NULL);
+ }
+ }
// Watchdog:
@@ -891,8 +955,11 @@
ForceShutdown = false;
if (timer)
dsyslog("next timer event at %s", *TimeToString(Next));
- if (WatchdogTimeout > 0)
- signal(SIGALRM, SIG_IGN);
+ if (WatchdogTimeout > 0) {
+ sa.sa_handler = SIG_IGN;
+ sa.sa_flags = 0;
+ sigaction(SIGALRM, &sa, NULL);
+ }
if (Interface->Confirm(tr("Press any key to cancel shutdown"), UserShutdown ? 5 : SHUTDOWNWAIT, true)) {
cControl::Shutdown();
int Channel = timer ? timer->Channel()->Number() : 0;
@@ -906,9 +973,19 @@
}
else if (WatchdogTimeout > 0) {
alarm(WatchdogTimeout);
+/*
if (signal(SIGALRM, Watchdog) == SIG_IGN)
signal(SIGALRM, SIG_IGN);
+*/
+ sa.sa_sigaction = Watchdog;
+ sa.sa_flags = SA_SIGINFO;
+ sigaction (SIGALRM, &sa, &oldsigact);
+ if (oldsigact.sa_handler == SIG_IGN) {
+ sa.sa_handler = SIG_IGN;
+ sa.sa_flags = 0;
+ sigaction (SIGALRM, &sa, NULL);
}
+ }
LastActivity = time(NULL); // don't try again too soon
UserShutdown = false;
continue; // skip the rest of the housekeeping for now
@@ -923,7 +1000,7 @@
}
}
if (Interrupted)
- isyslog("caught signal %d", Interrupted);
+ isyslog("caught signal %d from %d", Interrupted, Int_From);
Exit: