From 5636f3a8a2d4564aaddf424d62723aac7f4d45fe Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Tue, 15 Mar 2011 21:36:36 -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 d80eae2c8..65d6c0ce8 100644 --- a/src/events/SDL_quit.c +++ b/src/events/SDL_quit.c @@ -45,7 +45,19 @@ static void SDL_HandleSIG(int sig) /* Public functions */ 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 */ @@ -62,7 +74,19 @@ int 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);