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 5492b214b7ce9b00
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
     1.1 --- a/src/events/SDL_quit.c	Thu Feb 24 17:42:45 2011 -0800
     1.2 +++ b/src/events/SDL_quit.c	Tue Mar 15 21:36:36 2011 -0700
     1.3 @@ -45,7 +45,19 @@
     1.4  /* Public functions */
     1.5  int SDL_QuitInit(void)
     1.6  {
     1.7 -#ifdef HAVE_SIGNAL_H
     1.8 +#ifdef HAVE_SIGACTION
     1.9 +	struct sigaction action;
    1.10 +	sigaction(SIGINT, NULL, &action);
    1.11 +	if ( action.sa_handler == SIG_DFL && action.sa_sigaction == SIG_DFL ) {
    1.12 +		action.sa_handler = SDL_HandleSIG;
    1.13 +		sigaction(SIGINT, &action, NULL);
    1.14 +	}
    1.15 +	sigaction(SIGTERM, NULL, &action);
    1.16 +	if ( action.sa_handler == SIG_DFL && action.sa_sigaction == SIG_DFL ) {
    1.17 +		action.sa_handler = SDL_HandleSIG;
    1.18 +		sigaction(SIGTERM, &action, NULL);
    1.19 +	}
    1.20 +#elif HAVE_SIGNAL_H
    1.21  	void (*ohandler)(int);
    1.22  
    1.23  	/* Both SIGINT and SIGTERM are translated into quit interrupts */
    1.24 @@ -62,7 +74,19 @@
    1.25  }
    1.26  void SDL_QuitQuit(void)
    1.27  {
    1.28 -#ifdef HAVE_SIGNAL_H
    1.29 +#ifdef HAVE_SIGACTION
    1.30 +	struct sigaction action;
    1.31 +	sigaction(SIGINT, NULL, &action);
    1.32 +	if ( action.sa_handler == SDL_HandleSIG ) {
    1.33 +		action.sa_handler = SIG_DFL;
    1.34 +		sigaction(SIGINT, &action, NULL);
    1.35 +	}
    1.36 +	sigaction(SIGTERM, NULL, &action);
    1.37 +	if ( action.sa_handler == SDL_HandleSIG ) {
    1.38 +		action.sa_handler = SIG_DFL;
    1.39 +		sigaction(SIGTERM, &action, NULL);
    1.40 +	}
    1.41 +#elif HAVE_SIGNAL_H
    1.42  	void (*ohandler)(int);
    1.43  
    1.44  	ohandler = signal(SIGINT, SIG_DFL);