From 885f507317b6c8576ba2e298c2249d27ea6f8404 Mon Sep 17 00:00:00 2001 From: Denis Vlasenko Date: Mon, 15 Dec 2008 09:29:33 +0000 Subject: sigaction overhaul as described in docs/sigaction.txt Run tested on i386. --- libc/sysdeps/linux/arm/sigaction.c | 90 ++++++++++++-------------------------- 1 file changed, 29 insertions(+), 61 deletions(-) (limited to 'libc/sysdeps/linux/arm/sigaction.c') diff --git a/libc/sysdeps/linux/arm/sigaction.c b/libc/sysdeps/linux/arm/sigaction.c index 2307d7add..01140aafb 100644 --- a/libc/sysdeps/linux/arm/sigaction.c +++ b/libc/sysdeps/linux/arm/sigaction.c @@ -34,100 +34,68 @@ extern __typeof(sigaction) __libc_sigaction; /* When RT signals are in use we need to use a different return stub. */ #ifdef __NR_rt_sigreturn #define choose_restorer(flags) \ - (flags & SA_SIGINFO) ? __default_rt_sa_restorer \ - : __default_sa_restorer + (flags & SA_SIGINFO) ? __default_rt_sa_restorer \ + : __default_sa_restorer #else #define choose_restorer(flags) \ - __default_sa_restorer + __default_sa_restorer #endif + #ifdef __NR_rt_sigaction -/* Experimentally off - libc_hidden_proto(memcpy) */ +/* If ACT is not NULL, change the action for SIG to *ACT. + If OACT is not NULL, put the old action for SIG in *OACT. */ +int __libc_sigaction(int sig, const struct sigaction *act, struct sigaction *oact) +{ + struct sigaction kact; + if (act && !(act->sa_flags & SA_RESTORER)) { + memcpy(&kact, act, sizeof(kact)); + kact.sa_restorer = choose_restorer(kact.sa_flags); + kact.sa_flags |= SA_RESTORER; + act = &kact; + } + /* NB: kernel (as of 2.6.25) will return EINVAL + * if sizeof(act->sa_mask) does not match kernel's sizeof(sigset_t) */ + return __syscall_rt_sigaction(sig, act, oact, sizeof(act->sa_mask)); +} + +#else /* If ACT is not NULL, change the action for SIG to *ACT. If OACT is not NULL, put the old action for SIG in *OACT. */ -int __libc_sigaction (int sig, const struct sigaction *act, struct sigaction *oact) +int __libc_sigaction(int sig, const struct sigaction *act, struct sigaction *oact) { int result; - struct kernel_sigaction kact, koact; - enum { - SIGSET_MIN_SIZE = sizeof(kact.sa_mask) < sizeof(act->sa_mask) - ? sizeof(kact.sa_mask) : sizeof(act->sa_mask) - }; + struct old_kernel_sigaction kact, koact; if (act) { kact.k_sa_handler = act->sa_handler; - memcpy (&kact.sa_mask, &act->sa_mask, SIGSET_MIN_SIZE); + kact.sa_mask = act->sa_mask.__val[0]; kact.sa_flags = act->sa_flags; -# ifdef HAVE_SA_RESTORER if (kact.sa_flags & SA_RESTORER) { kact.sa_restorer = act->sa_restorer; } else { - kact.sa_restorer = choose_restorer (kact.sa_flags); + kact.sa_restorer = choose_restorer(kact.sa_flags); kact.sa_flags |= SA_RESTORER; } -# endif } - - /* NB: kernel (as of 2.6.25) will return EINVAL - * if sizeof(kact.sa_mask) does not match kernel's sizeof(sigset_t) */ - result = __syscall_rt_sigaction(sig, + result = __syscall_sigaction(sig, act ? &kact : NULL, - oact ? &koact : NULL, - sizeof(kact.sa_mask)); - + oact ? &koact : NULL); if (oact && result >= 0) { oact->sa_handler = koact.k_sa_handler; - memcpy (&oact->sa_mask, &koact.sa_mask, SIGSET_MIN_SIZE); + oact->sa_mask.__val[0] = koact.sa_mask; oact->sa_flags = koact.sa_flags; -# ifdef HAVE_SA_RESTORER oact->sa_restorer = koact.sa_restorer; -# endif } return result; } - -#else - -/* If ACT is not NULL, change the action for SIG to *ACT. - If OACT is not NULL, put the old action for SIG in *OACT. */ -int __libc_sigaction (int sig, const struct sigaction *act, struct sigaction *oact) -{ - int result; - struct old_kernel_sigaction kact, koact; - - if (act) { - kact.k_sa_handler = act->sa_handler; - kact.sa_mask = act->sa_mask.__val[0]; - kact.sa_flags = act->sa_flags; -# ifdef HAVE_SA_RESTORER - if (kact.sa_flags & SA_RESTORER) { - kact.sa_restorer = act->sa_restorer; - } else { - kact.sa_restorer = choose_restorer (kact.sa_flags); - kact.sa_flags |= SA_RESTORER; - } -# endif - } - result = __syscall_sigaction(sig, act ? &kact : NULL, - oact ? &koact : NULL); - if (oact && result >= 0) { - oact->sa_handler = koact.k_sa_handler; - oact->sa_mask.__val[0] = koact.sa_mask; - oact->sa_flags = koact.sa_flags; -# ifdef HAVE_SA_RESTORER - oact->sa_restorer = koact.sa_restorer; -# endif - } - return result; -} - #endif + #ifndef LIBC_SIGACTION -/* libc_hidden_proto(sigaction) */ weak_alias(__libc_sigaction,sigaction) libc_hidden_weak(sigaction) #endif -- cgit v1.2.3