OSDN Git Service

sigaction overhaul as described in docs/sigaction.txt
[uclinux-h8/uClibc.git] / libc / signal / sigaction.c
index 25c1f8a..23a2d78 100644 (file)
 #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