OSDN Git Service

sigaction overhaul as described in docs/sigaction.txt
[uclinux-h8/uClibc.git] / libc / sysdeps / linux / arm / sigaction.c
index 2307d7a..01140aa 100644 (file)
@@ -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