From patchwork Tue Jul 5 06:20:31 2005 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Harald Milz X-Patchwork-Id: 11937 Received: from colin.muc.de ([193.149.48.1] helo=mail.muc.de ident=qmailr) by www.linuxtv.org with esmtp (Exim 4.34) id 1Dpgxg-0003Mw-Fo for vdr@linuxtv.org; Tue, 05 Jul 2005 08:31:16 +0200 Received: (qmail 41945 invoked by uid 66); 5 Jul 2005 06:31:14 -0000 Received: from seneca by colin2.muc.de with UUCP; Tue Jul 5 06:31:14 2005 -0000 Received: from nathan.muc.de (nathan [192.168.20.2]) by seneca.muc.de (Postfix) with ESMTP id 7FDD250BAEC for ; Tue, 5 Jul 2005 08:20:31 +0200 (CEST) Received: by nathan.muc.de (Postfix, from userid 2425) id 6BAD284C45; Tue, 5 Jul 2005 08:20:31 +0200 (CEST) From: Harald Milz To: vdr@linuxtv.org Summary: Keywords: User-Agent: tin/1.6.2-20030910 ("Pabbay") (UNIX) (Linux/2.6.8-24.14-default (x86_64)) Message-Id: <20050705062031.6BAD284C45@nathan.muc.de> Date: Tue, 5 Jul 2005 08:20:31 +0200 (CEST) Subject: [vdr] vdr-1.3.27 still gives me SIGINTs X-BeenThere: vdr@linuxtv.org X-Mailman-Version: 2.1.5 Precedence: list Reply-To: Klaus Schmidinger's VDR List-Id: Klaus Schmidinger's VDR List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 05 Jul 2005 06:31:16 -0000 Status: O X-Status: X-Keywords: X-UID: 3423 Hi, my living room vdr still gives me the goose bumps as far as SIGINTs from an unknown source (I posted that before... no clue who is the bad guy). Anyway, this patch keeps vdr from accepting SIGINTs from UID != 0. Ctrl-C as root still works. (And BTW signal() is deprecated, and the man page says about signal(2) Trying to change the semantics of this call using defines and includes is not a good idea. It is better to avoid signal altogether, and use sigaction(2) instead. NOTES The effects of this call in a multi-threaded process are unspecified. --- vdr-1.3.27/vdr.c 2005-06-18 13:19:07.000000000 +0200 +++ vdr-1.3.27-sigint/vdr.c 2005-07-03 23:32:20.709975045 +0200 @@ -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: