|  | @@ -21,6 +21,7 @@
 | 
	
		
			
				|  |  |  #include "internals.h"
 | 
	
		
			
				|  |  |  #include "spinlock.h"
 | 
	
		
			
				|  |  |  #include <ucontext.h>
 | 
	
		
			
				|  |  | +#include "debug.h"
 | 
	
		
			
				|  |  |  #include <bits/sigcontextinfo.h>
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  /* mods for uClibc: __libc_sigaction is not in any standard headers */
 | 
	
	
		
			
				|  | @@ -76,15 +77,11 @@ int pthread_kill(pthread_t thread, int signo)
 | 
	
		
			
				|  |  |      return 0;
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -/* User-provided signal handlers */
 | 
	
		
			
				|  |  | -static union
 | 
	
		
			
				|  |  | -{
 | 
	
		
			
				|  |  | -  arch_sighandler_t old;
 | 
	
		
			
				|  |  | -  void (*rt) (int, struct siginfo *, struct ucontext *);
 | 
	
		
			
				|  |  | -} sighandler[NSIG];
 | 
	
		
			
				|  |  | +union sighandler __sighandler[NSIG] =
 | 
	
		
			
				|  |  | +  { [1 ... NSIG - 1] = { (arch_sighandler_t) SIG_ERR } };
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  /* The wrapper around user-provided signal handlers */
 | 
	
		
			
				|  |  | -static void pthread_sighandler(int signo, SIGCONTEXT ctx)
 | 
	
		
			
				|  |  | +static void __pthread_sighandler(int signo, SIGCONTEXT ctx)
 | 
	
		
			
				|  |  |  {
 | 
	
		
			
				|  |  |    pthread_descr self = thread_self();
 | 
	
		
			
				|  |  |    char * in_sighandler;
 | 
	
	
		
			
				|  | @@ -100,13 +97,13 @@ static void pthread_sighandler(int signo, SIGCONTEXT ctx)
 | 
	
		
			
				|  |  |    in_sighandler = THREAD_GETMEM(self, p_in_sighandler);
 | 
	
		
			
				|  |  |    if (in_sighandler == NULL)
 | 
	
		
			
				|  |  |      THREAD_SETMEM(self, p_in_sighandler, CURRENT_STACK_FRAME);
 | 
	
		
			
				|  |  | -  sighandler[signo].old(signo, SIGCONTEXT_EXTRA_ARGS ctx);
 | 
	
		
			
				|  |  | +  __sighandler[signo].old(signo, SIGCONTEXT_EXTRA_ARGS ctx);
 | 
	
		
			
				|  |  |    if (in_sighandler == NULL)
 | 
	
		
			
				|  |  |      THREAD_SETMEM(self, p_in_sighandler, NULL);
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  /* The same, this time for real-time signals.  */
 | 
	
		
			
				|  |  | -static void pthread_sighandler_rt(int signo, struct siginfo *si,
 | 
	
		
			
				|  |  | +static void __pthread_sighandler_rt(int signo, struct siginfo *si,
 | 
	
		
			
				|  |  |  				  struct ucontext *uc)
 | 
	
		
			
				|  |  |  {
 | 
	
		
			
				|  |  |    pthread_descr self = thread_self();
 | 
	
	
		
			
				|  | @@ -123,7 +120,7 @@ static void pthread_sighandler_rt(int signo, struct siginfo *si,
 | 
	
		
			
				|  |  |    in_sighandler = THREAD_GETMEM(self, p_in_sighandler);
 | 
	
		
			
				|  |  |    if (in_sighandler == NULL)
 | 
	
		
			
				|  |  |      THREAD_SETMEM(self, p_in_sighandler, CURRENT_STACK_FRAME);
 | 
	
		
			
				|  |  | -  sighandler[signo].rt(signo, si, uc);
 | 
	
		
			
				|  |  | +  __sighandler[signo].rt(signo, si, uc);
 | 
	
		
			
				|  |  |    if (in_sighandler == NULL)
 | 
	
		
			
				|  |  |      THREAD_SETMEM(self, p_in_sighandler, NULL);
 | 
	
		
			
				|  |  |  }
 | 
	
	
		
			
				|  | @@ -135,14 +132,18 @@ int __sigaction(int sig, const struct sigaction * act,
 | 
	
		
			
				|  |  |  {
 | 
	
		
			
				|  |  |    struct sigaction newact;
 | 
	
		
			
				|  |  |    struct sigaction *newactp;
 | 
	
		
			
				|  |  | +  __sighandler_t old = SIG_DFL;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -#ifdef DEBUG_PT
 | 
	
		
			
				|  |  | -printf(__FUNCTION__": pthreads wrapper!\n");
 | 
	
		
			
				|  |  | -#endif
 | 
	
		
			
				|  |  | +  PDEBUG("pthreads wrapper!\n");
 | 
	
		
			
				|  |  |    if (sig == __pthread_sig_restart ||
 | 
	
		
			
				|  |  |        sig == __pthread_sig_cancel ||
 | 
	
		
			
				|  |  |        (sig == __pthread_sig_debug && __pthread_sig_debug > 0))
 | 
	
		
			
				|  |  | -    return EINVAL;
 | 
	
		
			
				|  |  | +    {
 | 
	
		
			
				|  |  | +      __set_errno (EINVAL);
 | 
	
		
			
				|  |  | +      return -1;
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +  if (sig > 0 && sig < NSIG)
 | 
	
		
			
				|  |  | +    old = (__sighandler_t) __sighandler[sig].old;
 | 
	
		
			
				|  |  |    if (act)
 | 
	
		
			
				|  |  |      {
 | 
	
		
			
				|  |  |        newact = *act;
 | 
	
	
		
			
				|  | @@ -150,27 +151,35 @@ printf(__FUNCTION__": pthreads wrapper!\n");
 | 
	
		
			
				|  |  |  	  && sig > 0 && sig < NSIG)
 | 
	
		
			
				|  |  |  	{
 | 
	
		
			
				|  |  |  	  if (act->sa_flags & SA_SIGINFO)
 | 
	
		
			
				|  |  | -	    newact.sa_handler = (__sighandler_t) pthread_sighandler_rt;
 | 
	
		
			
				|  |  | +	    newact.sa_handler = (__sighandler_t) __pthread_sighandler_rt;
 | 
	
		
			
				|  |  |  	  else
 | 
	
		
			
				|  |  | -	    newact.sa_handler = (__sighandler_t) pthread_sighandler;
 | 
	
		
			
				|  |  | +	    newact.sa_handler = (__sighandler_t) __pthread_sighandler;
 | 
	
		
			
				|  |  | +	  if (old == SIG_IGN || old == SIG_DFL || old == SIG_ERR)
 | 
	
		
			
				|  |  | +	    __sighandler[sig].old = (arch_sighandler_t) act->sa_handler;
 | 
	
		
			
				|  |  |  	}
 | 
	
		
			
				|  |  |        newactp = &newact;
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |    else
 | 
	
		
			
				|  |  |      newactp = NULL;
 | 
	
		
			
				|  |  |    if (__libc_sigaction(sig, newactp, oact) == -1)
 | 
	
		
			
				|  |  | -    return -1;
 | 
	
		
			
				|  |  | -#ifdef DEBUG_PT
 | 
	
		
			
				|  |  | -printf(__FUNCTION__": signahdler installed, __sigaction successful\n");
 | 
	
		
			
				|  |  | -#endif
 | 
	
		
			
				|  |  | +    {
 | 
	
		
			
				|  |  | +      if (act)
 | 
	
		
			
				|  |  | +	__sighandler[sig].old = (arch_sighandler_t) old;
 | 
	
		
			
				|  |  | +      return -1;
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +  PDEBUG("signahdler installed, __sigaction successful\n");
 | 
	
		
			
				|  |  |    if (sig > 0 && sig < NSIG)
 | 
	
		
			
				|  |  |      {
 | 
	
		
			
				|  |  | -      if (oact != NULL)
 | 
	
		
			
				|  |  | -	oact->sa_handler = (__sighandler_t) sighandler[sig].old;
 | 
	
		
			
				|  |  | +      if (oact != NULL
 | 
	
		
			
				|  |  | +	  /* We may have inherited SIG_IGN from the parent, so return the
 | 
	
		
			
				|  |  | +	     kernel's idea of the signal handler the first time
 | 
	
		
			
				|  |  | +	     through.  */
 | 
	
		
			
				|  |  | +	  && old != SIG_ERR)
 | 
	
		
			
				|  |  | +	oact->sa_handler = old;
 | 
	
		
			
				|  |  |        if (act)
 | 
	
		
			
				|  |  | -	/* For the assignment is does not matter whether it's a normal
 | 
	
		
			
				|  |  | +	/* For the assignment it does not matter whether it's a normal
 | 
	
		
			
				|  |  |  	   or real-time signal.  */
 | 
	
		
			
				|  |  | -	sighandler[sig].old = (arch_sighandler_t) act->sa_handler;
 | 
	
		
			
				|  |  | +	__sighandler[sig].old = (arch_sighandler_t) act->sa_handler;
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |    return 0;
 | 
	
		
			
				|  |  |  }
 | 
	
	
		
			
				|  | @@ -196,17 +205,17 @@ int sigwait(const sigset_t * set, int * sig)
 | 
	
		
			
				|  |  |       signals in set is unspecified." */
 | 
	
		
			
				|  |  |    sigfillset(&mask);
 | 
	
		
			
				|  |  |    sigdelset(&mask, __pthread_sig_cancel);
 | 
	
		
			
				|  |  | -  for (s = 1; s <= NSIG; s++) {
 | 
	
		
			
				|  |  | +  for (s = 1; s < NSIG; s++) {
 | 
	
		
			
				|  |  |      if (sigismember(set, s) &&
 | 
	
		
			
				|  |  |          s != __pthread_sig_restart &&
 | 
	
		
			
				|  |  |          s != __pthread_sig_cancel &&
 | 
	
		
			
				|  |  |          s != __pthread_sig_debug) {
 | 
	
		
			
				|  |  |        sigdelset(&mask, s);
 | 
	
		
			
				|  |  | -      if (sighandler[s].old == NULL ||
 | 
	
		
			
				|  |  | -	  sighandler[s].old == (arch_sighandler_t) SIG_DFL ||
 | 
	
		
			
				|  |  | -	  sighandler[s].old == (arch_sighandler_t) SIG_IGN) {
 | 
	
		
			
				|  |  | +      if (__sighandler[s].old == (arch_sighandler_t) SIG_ERR ||
 | 
	
		
			
				|  |  | +          __sighandler[s].old == (arch_sighandler_t) SIG_DFL ||
 | 
	
		
			
				|  |  | +          __sighandler[s].old == (arch_sighandler_t) SIG_IGN) {
 | 
	
		
			
				|  |  |          sa.sa_handler = pthread_null_sighandler;
 | 
	
		
			
				|  |  | -        sigemptyset(&sa.sa_mask);
 | 
	
		
			
				|  |  | +        sigfillset(&sa.sa_mask);
 | 
	
		
			
				|  |  |          sa.sa_flags = 0;
 | 
	
		
			
				|  |  |          sigaction(s, &sa, NULL);
 | 
	
		
			
				|  |  |        }
 |