diff options
Diffstat (limited to 'libc/signal')
-rw-r--r-- | libc/signal/sigaction.c | 61 |
1 files changed, 13 insertions, 48 deletions
diff --git a/libc/signal/sigaction.c b/libc/signal/sigaction.c index 25c1f8a74..23a2d78db 100644 --- a/libc/signal/sigaction.c +++ b/libc/signal/sigaction.c @@ -20,62 +20,30 @@ #include <errno.h> #include <signal.h> #include <string.h> - #include <sys/syscall.h> -/* Experimentally off - libc_hidden_proto(memcpy) */ - -/* The difference here is that the sigaction structure used in the - kernel is not the same as we use in the libc. Therefore we must - translate it here. */ #include <bits/kernel_sigaction.h> #ifndef LIBC_SIGACTION extern __typeof(sigaction) __libc_sigaction; #endif + #if defined __NR_rt_sigaction /* 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) +__libc_sigaction(int sig, const struct sigaction *act, struct sigaction *oact) { - int result; - struct kernel_sigaction kact, koact; - enum { - /* We try hard to actually have them equal, - * but just for paranoid reasons, be safe */ - SIGSET_MIN_SIZE = sizeof(kact.sa_mask) < sizeof(act->sa_mask) - ? sizeof(kact.sa_mask) : sizeof(act->sa_mask) - }; - - if (act) { - kact.k_sa_handler = act->sa_handler; - memcpy (&kact.sa_mask, &act->sa_mask, SIGSET_MIN_SIZE); - kact.sa_flags = act->sa_flags; -# ifdef HAVE_SA_RESTORER - kact.sa_restorer = act->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, - act ? &kact : NULL, - oact ? &koact : NULL, - sizeof(kact.sa_mask)); - - if (oact && result >= 0) { - oact->sa_handler = koact.k_sa_handler; - memcpy (&oact->sa_mask, &koact.sa_mask, SIGSET_MIN_SIZE); - oact->sa_flags = koact.sa_flags; -# ifdef HAVE_SA_RESTORER - oact->sa_restorer = koact.sa_restorer; -# endif - } - - return result; + * if sizeof(act->sa_mask) does not match kernel's sizeof(sigset_t). + * Try to catch this problem at uclibc build time: */ + struct BUG_sigset_size { + int BUG_sigset_size + [sizeof(act->sa_mask) != _NSIG / 8 ? 1 : -1]; + }; + return __syscall_rt_sigaction(sig, act, oact, sizeof(act->sa_mask)); } #else @@ -83,7 +51,7 @@ __libc_sigaction (int sig, const struct sigaction *act, struct sigaction *oact) /* 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) +__libc_sigaction(int sig, const struct sigaction *act, struct sigaction *oact) { int result; struct old_kernel_sigaction kact, koact; @@ -96,11 +64,9 @@ __libc_sigaction (int sig, const struct sigaction *act, struct sigaction *oact) kact.sa_restorer = act->sa_restorer; # endif } - result = __syscall_sigaction(sig, - act ? &kact : NULL, - oact ? &koact : NULL); - + 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; @@ -109,14 +75,13 @@ __libc_sigaction (int sig, const struct sigaction *act, struct sigaction *oact) 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 |