From 45e584dd37ceabc6567e72de613ddcae653e653c Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Tue, 15 Mar 2011 21:37:01 -0700 Subject: [PATCH] Do not break application's signal handler installed with SA_SIGINFO Gleb Natapov to sdl If application installs SIGINT/SIGTERM signal handler with sigaction(SA_SIGINFO) syscall before initializing SDL, after initialization of SDL signal handler will be reinstalled without SA_SIGINFO flag which brings havoc when the signal handler is called. The breakage is done by SDL_QuitInit()/SDL_QuitQuit() function. They use signal() to detect that signal handler is already installed even in sigaction() is available. --- src/events/SDL_quit.c | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/src/events/SDL_quit.c b/src/events/SDL_quit.c index c74a43473..2108693d5 100644 --- a/src/events/SDL_quit.c +++ b/src/events/SDL_quit.c @@ -47,7 +47,19 @@ SDL_HandleSIG(int sig) int SDL_QuitInit(void) { -#ifdef HAVE_SIGNAL_H +#ifdef HAVE_SIGACTION + struct sigaction action; + sigaction(SIGINT, NULL, &action); + if ( action.sa_handler == SIG_DFL && action.sa_sigaction == SIG_DFL ) { + action.sa_handler = SDL_HandleSIG; + sigaction(SIGINT, &action, NULL); + } + sigaction(SIGTERM, NULL, &action); + if ( action.sa_handler == SIG_DFL && action.sa_sigaction == SIG_DFL ) { + action.sa_handler = SDL_HandleSIG; + sigaction(SIGTERM, &action, NULL); + } +#elif HAVE_SIGNAL_H void (*ohandler) (int); /* Both SIGINT and SIGTERM are translated into quit interrupts */ @@ -66,7 +78,19 @@ SDL_QuitInit(void) void SDL_QuitQuit(void) { -#ifdef HAVE_SIGNAL_H +#ifdef HAVE_SIGACTION + struct sigaction action; + sigaction(SIGINT, NULL, &action); + if ( action.sa_handler == SDL_HandleSIG ) { + action.sa_handler = SIG_DFL; + sigaction(SIGINT, &action, NULL); + } + sigaction(SIGTERM, NULL, &action); + if ( action.sa_handler == SDL_HandleSIG ) { + action.sa_handler = SIG_DFL; + sigaction(SIGTERM, &action, NULL); + } +#elif HAVE_SIGNAL_H void (*ohandler) (int); ohandler = signal(SIGINT, SIG_DFL);