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.
--- a/src/events/SDL_quit.c Tue Mar 15 19:37:38 2011 -0700
+++ b/src/events/SDL_quit.c Tue Mar 15 21:37:01 2011 -0700
@@ -47,7 +47,19 @@
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 @@
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);