Do not break application's signal handler installed with SA_SIGINFO SDL-1.2
authorSam Lantinga <slouken@libsdl.org>
Tue, 15 Mar 2011 21:36:36 -0700
branchSDL-1.2
changeset 5492 b214b7ce9b00
parent 5394 67d3be4ec9f2
child 5500 27348c0ae529
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
--- a/src/events/SDL_quit.c	Thu Feb 24 17:42:45 2011 -0800
+++ b/src/events/SDL_quit.c	Tue Mar 15 21:36:36 2011 -0700
@@ -45,7 +45,19 @@
 /* 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 @@
 }
 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);