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. --- docs/sigaction.txt | 6 +- include/signal.h | 33 +++-- libc/signal/sigaction.c | 61 ++------ libc/sysdeps/linux/alpha/bits/kernel_sigaction.h | 15 +- libc/sysdeps/linux/alpha/bits/sigaction.h | 33 ++--- libc/sysdeps/linux/arm/sigaction.c | 90 ++++-------- libc/sysdeps/linux/avr32/sigaction.c | 42 ++---- libc/sysdeps/linux/common/bits/kernel_sigaction.h | 67 ++------- libc/sysdeps/linux/common/bits/sigaction.h | 42 +++--- libc/sysdeps/linux/common/bits/sigset.h | 6 +- libc/sysdeps/linux/hppa/bits/kernel_sigaction.h | 15 +- libc/sysdeps/linux/hppa/bits/sigaction.h | 33 ++--- libc/sysdeps/linux/i386/sigaction.c | 158 +++++++++------------ libc/sysdeps/linux/ia64/bits/sigaction.h | 33 ++--- libc/sysdeps/linux/mips/bits/kernel_sigaction.h | 25 +--- libc/sysdeps/linux/mips/bits/sigaction.h | 41 ++---- libc/sysdeps/linux/mips/sigaction.c | 137 +++++++----------- libc/sysdeps/linux/sparc/bits/sigaction.h | 36 ++--- libc/sysdeps/linux/x86_64/sigaction.c | 89 +++++------- libc/sysdeps/linux/xtensa/sigaction.c | 47 ++---- .../linuxthreads/sysdeps/pthread/sigaction.c | 2 + 21 files changed, 355 insertions(+), 656 deletions(-) diff --git a/docs/sigaction.txt b/docs/sigaction.txt index b380e725b..667eeba41 100644 --- a/docs/sigaction.txt +++ b/docs/sigaction.txt @@ -242,4 +242,8 @@ To this effect: * Document discovered arch quirks while debugging this mess. -* Deal with old_kernel_sigaction later. +* struct old_kernel_sigaction can't be disposed of in a similar way, + we need to have userspace struct sigaction unchanged regardless + whether we use "old" or "new" kernel sigaction() syscall. + It's moot anyway because "old" one is long unused, it's from + pre-2.2 kernels. diff --git a/include/signal.h b/include/signal.h index 2946f9c5f..c2b8b7476 100644 --- a/include/signal.h +++ b/include/signal.h @@ -56,13 +56,23 @@ typedef __sigset_t sigset_t; #include #include +//TODO vda: pull out of bits/signum.h the following, +//which is the same for all arches: +//#define SIG_ERR ((__sighandler_t) -1) /* Error return. */ +//#define SIG_DFL ((__sighandler_t) 0) /* Default action. */ +//#define SIG_IGN ((__sighandler_t) 1) /* Ignore signal. */ +//#ifdef __USE_UNIX98 +//# define SIG_HOLD ((__sighandler_t) 2) /* Add signal to hold mask. */ +//#endif +//#define SIGRTMIN (__libc_current_sigrtmin()) +//#define SIGRTMAX (__libc_current_sigrtmax()) +//#define __SIGRTMIN -- dont pull, it's arch specific +//#define __SIGRTMAX (_NSIG - 1) #if defined __USE_XOPEN || defined __USE_XOPEN2K # ifndef __pid_t_defined typedef __pid_t pid_t; # define __pid_t_defined -#endif -#ifdef __USE_XOPEN # endif # ifndef __uid_t_defined typedef __uid_t uid_t; @@ -79,10 +89,10 @@ typedef void (*__sighandler_t) (int); requested. */ extern __sighandler_t __sysv_signal (int __sig, __sighandler_t __handler) __THROW; -#ifdef __USE_GNU +# ifdef __USE_GNU extern __sighandler_t sysv_signal (int __sig, __sighandler_t __handler) __THROW; -#endif +# endif #endif /* __UCLIBC_HAS_OBSOLETE_SYSV_SIGNAL__ */ /* Set the handler for the signal SIG to HANDLER, returning the old @@ -118,14 +128,14 @@ extern __sighandler_t bsd_signal (int __sig, __sighandler_t __handler) #ifdef __USE_POSIX extern int kill (__pid_t __pid, int __sig) __THROW; libc_hidden_proto(kill) -#endif /* Use POSIX. */ +#endif #if defined __USE_BSD || defined __USE_XOPEN_EXTENDED /* Send SIG to all processes in process group PGRP. If PGRP is zero, send SIG to all processes in the current process's process group. */ extern int killpg (__pid_t __pgrp, int __sig) __THROW; -#endif /* Use BSD || X/Open Unix. */ +#endif __BEGIN_NAMESPACE_STD /* Raise signal SIG, i.e., send SIG to yourself. */ @@ -195,8 +205,9 @@ extern int siggetmask (void) __THROW __attribute_deprecated__; #endif /* Use BSD. */ +/* Biggest signal number + 1 (including real-time signals). */ #ifdef __USE_MISC -# define NSIG _NSIG +# define NSIG _NSIG #endif #ifdef __USE_GNU @@ -316,12 +327,12 @@ extern int sigqueue (__pid_t __pid, int __sig, __const union sigval __val) #ifdef __USE_BSD -#ifdef __UCLIBC_HAS_SYS_SIGLIST__ +# ifdef __UCLIBC_HAS_SYS_SIGLIST__ /* Names of the signals. This variable exists only for compatibility. Use `strsignal' instead (see ). */ -#define _sys_siglist sys_siglist +# define _sys_siglist sys_siglist extern __const char *__const sys_siglist[_NSIG]; -#endif /* __UCLIBC_HAS_SYS_SIGLIST__ */ +# endif /* Structure passed to `sigvec'. */ struct sigvec @@ -404,7 +415,7 @@ extern __sighandler_t sigset (int __sig, __sighandler_t __disp) __THROW; be defined here. */ # include # include -#endif /* use Unix98 */ +#endif /* The following functions are used internally in the C library and in other code which need deep insights. */ 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 #include #include - #include -/* 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 #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 diff --git a/libc/sysdeps/linux/alpha/bits/kernel_sigaction.h b/libc/sysdeps/linux/alpha/bits/kernel_sigaction.h index 626af23fb..cd6b2133d 100644 --- a/libc/sysdeps/linux/alpha/bits/kernel_sigaction.h +++ b/libc/sysdeps/linux/alpha/bits/kernel_sigaction.h @@ -9,15 +9,12 @@ struct old_kernel_sigaction { unsigned int sa_flags; }; -/* This is the sigaction structure from the Linux 2.1.68 kernel. */ +/* In uclibc, userspace struct sigaction is identical to + * "new" struct kernel_sigaction (one from the Linux 2.1.68 kernel). + * See sigaction.h + */ -struct kernel_sigaction { - __sighandler_t k_sa_handler; - unsigned int sa_flags; - sigset_t sa_mask; -}; - -extern int __syscall_rt_sigaction (int, const struct kernel_sigaction *, - struct kernel_sigaction *, size_t) attribute_hidden; +extern int __syscall_rt_sigaction (int, const struct sigaction *, + struct sigaction *, size_t) attribute_hidden; #endif diff --git a/libc/sysdeps/linux/alpha/bits/sigaction.h b/libc/sysdeps/linux/alpha/bits/sigaction.h index 80feb2fa2..61dea1180 100644 --- a/libc/sysdeps/linux/alpha/bits/sigaction.h +++ b/libc/sysdeps/linux/alpha/bits/sigaction.h @@ -22,30 +22,21 @@ #endif /* Structure describing the action to be taken when a signal arrives. */ -struct sigaction - { - /* Signal handler. */ +struct sigaction { #ifdef __USE_POSIX199309 - union - { - /* Used if SA_SIGINFO is not set. */ - __sighandler_t sa_handler; - /* Used if SA_SIGINFO is set. */ - void (*sa_sigaction) (int, siginfo_t *, void *); - } - __sigaction_handler; -# define sa_handler __sigaction_handler.sa_handler -# define sa_sigaction __sigaction_handler.sa_sigaction + union { + __sighandler_t sa_handler; + void (*sa_sigaction)(int, siginfo_t *, void *); + } __sigaction_handler; +# define sa_handler __sigaction_handler.sa_handler +# define sa_sigaction __sigaction_handler.sa_sigaction #else - __sighandler_t sa_handler; + __sighandler_t sa_handler; #endif - - /* Additional set of signals to be blocked. */ - __sigset_t sa_mask; - - /* Special flags. */ - unsigned int sa_flags; - }; + unsigned sa_flags; + sigset_t sa_mask; + /* Alpha has no sa_restorer field. */ +}; /* Bits in `sa_flags'. */ #define SA_NOCLDSTOP 0x00000004 /* Don't send SIGCHLD when children stop. */ 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 diff --git a/libc/sysdeps/linux/avr32/sigaction.c b/libc/sysdeps/linux/avr32/sigaction.c index 8113c9ca6..61530912e 100644 --- a/libc/sysdeps/linux/avr32/sigaction.c +++ b/libc/sysdeps/linux/avr32/sigaction.c @@ -14,54 +14,30 @@ #define SA_RESTORER 0x04000000 extern void __default_rt_sa_restorer(void); -/* Experimentally off - libc_hidden_proto(memcpy) */ - extern __typeof(sigaction) __libc_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 signum, const struct sigaction *act, - struct sigaction *oldact) +int __libc_sigaction(int sig, const struct sigaction *act, + struct sigaction *oact) { - struct kernel_sigaction kact, koact; - int result; - enum { - SIGSET_MIN_SIZE = sizeof(kact.sa_mask) < sizeof(act->sa_mask) - ? sizeof(kact.sa_mask) : sizeof(act->sa_mask) - }; + struct sigaction kact; - 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; - if (kact.sa_flags & SA_RESTORER) - kact.sa_restorer = act->sa_restorer; - else - kact.sa_restorer = __default_rt_sa_restorer; + if (act && !(act->sa_flags & SA_RESTORER)) { + memcpy(&kact, act, sizeof(kact)); + kact.sa_restorer = __default_rt_sa_restorer; kact.sa_flags |= SA_RESTORER; + act = &kact; } /* 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(signum, - act ? &kact : NULL, - oldact ? &koact : NULL, - sizeof(kact.sa_mask)); - - if (oldact && result >= 0) { - oldact->sa_handler = koact.k_sa_handler; - memcpy(&oldact->sa_mask, &koact.sa_mask, SIGSET_MIN_SIZE); - oldact->sa_flags = koact.sa_flags; - oldact->sa_restorer = koact.sa_restorer; - } - - return result; + * if sizeof(act->sa_mask) does not match kernel's sizeof(sigset_t) */ + return __syscall_rt_sigaction(sig, act, oact, sizeof(act->sa_mask)); } #ifndef LIBC_SIGACTION -/* libc_hidden_proto(sigaction) */ weak_alias(__libc_sigaction, sigaction) libc_hidden_weak(sigaction) #endif diff --git a/libc/sysdeps/linux/common/bits/kernel_sigaction.h b/libc/sysdeps/linux/common/bits/kernel_sigaction.h index a39aa324b..f74e0a28a 100644 --- a/libc/sysdeps/linux/common/bits/kernel_sigaction.h +++ b/libc/sysdeps/linux/common/bits/kernel_sigaction.h @@ -4,72 +4,33 @@ /* This file provides whatever this particular arch's kernel thinks * the sigaction struct should look like... */ -#undef NO_OLD_SIGACTION -#if defined(__mips__) -/* We have libc/sysdeps/linux/mips/bits/kernel_sigaction.h, - * so this should never be used. Lets see whether it is true. */ -struct BUG_is_here { char BUG_is_here[-1]; }; +#if defined(__ia64__) #undef HAVE_SA_RESTORER -/* This is the sigaction structure from the Linux 2.1.24 kernel. */ -#include -struct old_kernel_sigaction { - __sighandler_t k_sa_handler; - unsigned int sa_flags; - unsigned long sa_mask; -}; -#define _KERNEL_NSIG 128 -#define _KERNEL_NSIG_BPW 32 -#define _KERNEL_NSIG_WORDS (_KERNEL_NSIG / _KERNEL_NSIG_BPW) -typedef struct { - unsigned long sig[_KERNEL_NSIG_WORDS]; -} kernel_sigset_t; -/* This is the sigaction structure from the Linux 2.1.68 kernel. */ -struct kernel_sigaction { - unsigned int sa_flags; - __sighandler_t k_sa_handler; - kernel_sigset_t sa_mask; - void (*sa_restorer)(void); - int s_resv[1]; /* reserved */ -}; - -#elif defined(__ia64__) - -#define NO_OLD_SIGACTION -#undef HAVE_SA_RESTORER -struct kernel_sigaction { - __sighandler_t k_sa_handler; - unsigned long sa_flags; - sigset_t sa_mask; -}; #else #define HAVE_SA_RESTORER /* This is the sigaction structure from the Linux 2.1.20 kernel. */ struct old_kernel_sigaction { - __sighandler_t k_sa_handler; - unsigned long sa_mask; - unsigned long sa_flags; - void (*sa_restorer) (void); -}; -/* This is the sigaction structure from the Linux 2.1.68 kernel. */ -struct kernel_sigaction { - __sighandler_t k_sa_handler; - unsigned long sa_flags; - void (*sa_restorer) (void); - sigset_t sa_mask; + __sighandler_t k_sa_handler; + unsigned long sa_mask; + unsigned long sa_flags; + void (*sa_restorer)(void); }; +/* In uclibc, userspace struct sigaction is identical to + * "new" struct kernel_sigaction (one from the Linux 2.1.68 kernel). + * See sigaction.h + */ -#endif - -#ifndef NO_OLD_SIGACTION -extern int __syscall_sigaction (int, const struct old_kernel_sigaction *, +extern int __syscall_sigaction(int, const struct old_kernel_sigaction *, struct old_kernel_sigaction *) attribute_hidden; + #endif -extern int __syscall_rt_sigaction (int, const struct kernel_sigaction *, - struct kernel_sigaction *, size_t) attribute_hidden; + +extern int __syscall_rt_sigaction(int, const struct sigaction *, + struct sigaction *, size_t) attribute_hidden; #endif /* _BITS_SIGACTION_STRUCT_H */ diff --git a/libc/sysdeps/linux/common/bits/sigaction.h b/libc/sysdeps/linux/common/bits/sigaction.h index 48cc5312f..7489aa878 100644 --- a/libc/sysdeps/linux/common/bits/sigaction.h +++ b/libc/sysdeps/linux/common/bits/sigaction.h @@ -21,34 +21,26 @@ # error "Never include directly; use instead." #endif -/* Structure describing the action to be taken when a signal arrives. */ -struct sigaction - { - /* Signal handler. */ +/* Structure describing the action to be taken when a signal arrives. + * In uclibc, it is identical to "new" struct kernel_sigaction + * (one from the Linux 2.1.68 kernel). + * This minimizes amount of translation in sigaction(). + */ +struct sigaction { #ifdef __USE_POSIX199309 - union - { - /* Used if SA_SIGINFO is not set. */ - __sighandler_t sa_handler; - /* Used if SA_SIGINFO is set. */ - void (*sa_sigaction) (int, siginfo_t *, void *); - } - __sigaction_handler; -# define sa_handler __sigaction_handler.sa_handler -# define sa_sigaction __sigaction_handler.sa_sigaction + union { + __sighandler_t sa_handler; + void (*sa_sigaction)(int, siginfo_t *, void *); + } __sigaction_handler; +# define sa_handler __sigaction_handler.sa_handler +# define sa_sigaction __sigaction_handler.sa_sigaction #else - __sighandler_t sa_handler; + __sighandler_t sa_handler; #endif - - /* Additional set of signals to be blocked. */ - __sigset_t sa_mask; - - /* Special flags. */ - int sa_flags; - - /* Restore handler. */ - void (*sa_restorer) (void); - }; + unsigned long sa_flags; + void (*sa_restorer)(void); + sigset_t sa_mask; +}; /* Bits in `sa_flags'. */ #define SA_NOCLDSTOP 1 /* Don't send SIGCHLD when children stop. */ diff --git a/libc/sysdeps/linux/common/bits/sigset.h b/libc/sysdeps/linux/common/bits/sigset.h index 7ec87eb1d..2f67a4ebf 100644 --- a/libc/sysdeps/linux/common/bits/sigset.h +++ b/libc/sysdeps/linux/common/bits/sigset.h @@ -29,10 +29,8 @@ typedef int __sig_atomic_t; * where they might have (or had in the past) 32 signals only, * I hope it's irrelevant now. * Signal 0 does not exist, so we have signals 1..64, not 0..63. - * Note that struct sigaction has embedded sigset_t, - * and this necessitates translation in sigaction() - * to convert it to struct kernel_sigaction. - * See libc/.../sigaction.c, libc/.../kernel_sigaction.h + * In uclibc, kernel and userspace sigset_t is always the same. + * BTW, struct sigaction is also the same on kernel and userspace side. */ #if defined(__mips__) # define _SIGSET_NWORDS (128 / (8 * sizeof (unsigned long))) diff --git a/libc/sysdeps/linux/hppa/bits/kernel_sigaction.h b/libc/sysdeps/linux/hppa/bits/kernel_sigaction.h index 8a8491da0..1c093a522 100644 --- a/libc/sysdeps/linux/hppa/bits/kernel_sigaction.h +++ b/libc/sysdeps/linux/hppa/bits/kernel_sigaction.h @@ -12,15 +12,12 @@ struct old_kernel_sigaction { unsigned long sa_flags; }; -/* This is the sigaction structure from the Linux 2.1.68 kernel. */ +/* In uclibc, userspace struct sigaction is identical to + * "new" struct kernel_sigaction (one from the Linux 2.1.68 kernel). + * See sigaction.h + */ -struct kernel_sigaction { - __sighandler_t k_sa_handler; - unsigned long sa_flags; - sigset_t sa_mask; -}; - -extern int __syscall_rt_sigaction (int, const struct kernel_sigaction *, - struct kernel_sigaction *, size_t) attribute_hidden; +extern int __syscall_rt_sigaction (int, const struct sigaction *, + struct sigaction *, size_t) attribute_hidden; #endif diff --git a/libc/sysdeps/linux/hppa/bits/sigaction.h b/libc/sysdeps/linux/hppa/bits/sigaction.h index 33f2b237b..3dac69e73 100644 --- a/libc/sysdeps/linux/hppa/bits/sigaction.h +++ b/libc/sysdeps/linux/hppa/bits/sigaction.h @@ -22,30 +22,21 @@ #endif /* Structure describing the action to be taken when a signal arrives. */ -struct sigaction - { - /* Signal handler. */ +struct sigaction { #ifdef __USE_POSIX199309 - union - { - /* Used if SA_SIGINFO is not set. */ - __sighandler_t sa_handler; - /* Used if SA_SIGINFO is set. */ - void (*sa_sigaction) (int, siginfo_t *, void *); - } - __sigaction_handler; -# define sa_handler __sigaction_handler.sa_handler -# define sa_sigaction __sigaction_handler.sa_sigaction + union { + __sighandler_t sa_handler; + void (*sa_sigaction)(int, siginfo_t *, void *); + } __sigaction_handler; +# define sa_handler __sigaction_handler.sa_handler +# define sa_sigaction __sigaction_handler.sa_sigaction #else - __sighandler_t sa_handler; + __sighandler_t sa_handler; #endif - - /* Special flags. */ - unsigned long int sa_flags; - - /* Additional set of signals to be blocked. */ - __sigset_t sa_mask; - }; + unsigned long sa_flags; + sigset_t sa_mask; + /* HPPA has no sa_restorer field. */ +}; /* Bits in `sa_flags'. */ diff --git a/libc/sysdeps/linux/i386/sigaction.c b/libc/sysdeps/linux/i386/sigaction.c index a69c872a7..602f759a4 100644 --- a/libc/sysdeps/linux/i386/sigaction.c +++ b/libc/sysdeps/linux/i386/sigaction.c @@ -29,115 +29,89 @@ extern __typeof(sigaction) __libc_sigaction; + #if defined __NR_rt_sigaction -/* Experimentally off - libc_hidden_proto(memcpy) */ -extern void restore_rt (void) __asm__ ("__restore_rt") attribute_hidden; -extern void restore (void) __asm__ ("__restore") attribute_hidden; +extern void restore_rt(void) __asm__ ("__restore_rt") attribute_hidden; +extern void restore(void) __asm__ ("__restore") attribute_hidden; /* 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 sigaction kact; #ifdef SIGCANCEL if (sig == SIGCANCEL) { - __set_errno (EINVAL); + __set_errno(EINVAL); return -1; } #endif - 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; - - kact.sa_flags = act->sa_flags | SA_RESTORER; - kact.sa_restorer = ((act->sa_flags & SA_SIGINFO) - ? &restore_rt : &restore); + memcpy(&kact, act, sizeof(kact)); + kact.sa_flags |= SA_RESTORER; + kact.sa_restorer = (act->sa_flags & SA_SIGINFO) ? &restore_rt : &restore; + act = &kact; } - /* 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; - oact->sa_restorer = koact.sa_restorer; - } - return result; + * 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 -extern void restore (void) __asm__ ("__restore") attribute_hidden; + +extern void restore(void) __asm__ ("__restore") attribute_hidden; /* 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 old_kernel_sigaction kact, koact; + int result; + struct old_kernel_sigaction kact, koact; #ifdef SIGCANCEL - if (sig == SIGCANCEL) { - __set_errno (EINVAL); - return -1; - } + if (sig == SIGCANCEL) { + __set_errno(EINVAL); + return -1; + } #endif - - if (act) { - kact.k_sa_handler = act->sa_handler; - kact.sa_mask = act->sa_mask.__val[0]; - kact.sa_flags = act->sa_flags | SA_RESTORER; - kact.sa_restorer = &restore; - } - - __asm__ __volatile__ ("pushl %%ebx\n" - "movl %3, %%ebx\n" - "int $0x80\n" - "popl %%ebx" - : "=a" (result), "=m" (koact) - : "0" (__NR_sigaction), "r" (sig), "m" (kact), - "c" (act ? &kact : 0), - "d" (oact ? &koact : 0)); - - if (result < 0) { - __set_errno(-result); - return -1; - } - - if (oact) { - oact->sa_handler = koact.k_sa_handler; - oact->sa_mask.__val[0] = koact.sa_mask; - oact->sa_flags = koact.sa_flags; - oact->sa_restorer = koact.sa_restorer; - } - return result; + if (act) { + kact.k_sa_handler = act->sa_handler; + kact.sa_mask = act->sa_mask.__val[0]; + kact.sa_flags = act->sa_flags | SA_RESTORER; + kact.sa_restorer = &restore; + } + __asm__ __volatile__ ( + " pushl %%ebx\n" + " movl %3, %%ebx\n" + " int $0x80\n" + " popl %%ebx\n" + : "=a" (result), "=m" (koact) + : "0" (__NR_sigaction), "r" (sig), "m" (kact), + "c" (act ? &kact : NULL), + "d" (oact ? &koact : NULL)); + if (result < 0) { + __set_errno(-result); + return -1; + } + if (oact) { + oact->sa_handler = koact.k_sa_handler; + oact->sa_mask.__val[0] = koact.sa_mask; + oact->sa_flags = koact.sa_flags; + oact->sa_restorer = koact.sa_restorer; + } + return result; } #endif + #ifndef LIBC_SIGACTION -/* libc_hidden_proto(sigaction) */ weak_alias(__libc_sigaction,sigaction) libc_hidden_weak(sigaction) #endif - - /* NOTE: Please think twice before making any changes to the bits of code below. GDB needs some intimate knowledge about it to recognize them as signal trampolines, and make backtraces through @@ -146,33 +120,31 @@ libc_hidden_weak(sigaction) If you ever feel the need to make any changes, please notify the appropriate GDB maintainer. */ -#define RESTORE(name, syscall) RESTORE2 (name, syscall) +#define RESTORE(name, syscall) RESTORE2(name, syscall) #define RESTORE2(name, syscall) \ -__asm__ \ - ( \ - ".text\n" \ - "__" #name ":\n" \ - " movl $" #syscall ", %eax\n" \ - " int $0x80" \ - ); +__asm__ ( \ + ".text\n" \ + "__" #name ":\n" \ + " movl $" #syscall ", %eax\n" \ + " int $0x80\n" \ +); #ifdef __NR_rt_sigaction /* The return code for realtime-signals. */ -RESTORE (restore_rt, __NR_rt_sigreturn) +RESTORE(restore_rt, __NR_rt_sigreturn) #endif #ifdef __NR_sigreturn /* For the boring old signals. */ # undef RESTORE2 # define RESTORE2(name, syscall) \ -__asm__ \ - ( \ - ".text\n" \ - "__" #name ":\n" \ - " popl %eax\n" \ - " movl $" #syscall ", %eax\n" \ - " int $0x80" \ - ); - -RESTORE (restore, __NR_sigreturn) +__asm__ ( \ + ".text\n" \ + "__" #name ":\n" \ + " popl %eax\n" \ + " movl $" #syscall ", %eax\n" \ + " int $0x80\n" \ +); + +RESTORE(restore, __NR_sigreturn) #endif diff --git a/libc/sysdeps/linux/ia64/bits/sigaction.h b/libc/sysdeps/linux/ia64/bits/sigaction.h index 11599d520..4049402c1 100644 --- a/libc/sysdeps/linux/ia64/bits/sigaction.h +++ b/libc/sysdeps/linux/ia64/bits/sigaction.h @@ -22,30 +22,21 @@ #endif /* Structure describing the action to be taken when a signal arrives. */ -struct sigaction - { - /* Signal handler. */ +struct sigaction { #ifdef __USE_POSIX199309 - union - { - /* Used if SA_SIGINFO is not set. */ - __sighandler_t sa_handler; - /* Used if SA_SIGINFO is set. */ - void (*sa_sigaction) (int, siginfo_t *, void *); - } - __sigaction_handler; -# define sa_handler __sigaction_handler.sa_handler -# define sa_sigaction __sigaction_handler.sa_sigaction + union { + __sighandler_t sa_handler; + void (*sa_sigaction)(int, siginfo_t *, void *); + } __sigaction_handler; +# define sa_handler __sigaction_handler.sa_handler +# define sa_sigaction __sigaction_handler.sa_sigaction #else - __sighandler_t sa_handler; + __sighandler_t sa_handler; #endif - - /* Special flags. */ - unsigned long int sa_flags; - - /* Additional set of signals to be blocked. */ - __sigset_t sa_mask; - }; + unsigned long sa_flags; + sigset_t sa_mask; + /* IA64 has no sa_restorer field. */ +}; /* Bits in `sa_flags'. */ #define SA_NOCLDSTOP 0x00000001 /* Don't send SIGCHLD when children stop. */ diff --git a/libc/sysdeps/linux/mips/bits/kernel_sigaction.h b/libc/sysdeps/linux/mips/bits/kernel_sigaction.h index 6a7b939c4..2048095c8 100644 --- a/libc/sysdeps/linux/mips/bits/kernel_sigaction.h +++ b/libc/sysdeps/linux/mips/bits/kernel_sigaction.h @@ -24,25 +24,12 @@ struct old_kernel_sigaction { #endif }; +/* In uclibc, userspace struct sigaction is identical to + * "new" struct kernel_sigaction (one from the Linux 2.1.68 kernel). + * See sigaction.h + */ -#define _KERNEL_NSIG 128 -#define _KERNEL_NSIG_BPW _MIPS_SZLONG -#define _KERNEL_NSIG_WORDS (_KERNEL_NSIG / _KERNEL_NSIG_BPW) - -typedef struct { - unsigned long sig[_KERNEL_NSIG_WORDS]; -} kernel_sigset_t; - -/* This is the sigaction structure from the Linux 2.1.68 kernel. */ -struct kernel_sigaction { - unsigned int sa_flags; - __sighandler_t k_sa_handler; - kernel_sigset_t sa_mask; - void (*sa_restorer)(void); - int s_resv[1]; /* reserved */ -}; - -extern int __syscall_rt_sigaction (int, const struct kernel_sigaction *, - struct kernel_sigaction *, size_t) attribute_hidden; +extern int __syscall_rt_sigaction (int, const struct sigaction *, + struct sigaction *, size_t) attribute_hidden; #endif diff --git a/libc/sysdeps/linux/mips/bits/sigaction.h b/libc/sysdeps/linux/mips/bits/sigaction.h index d04e25f76..cc689d149 100644 --- a/libc/sysdeps/linux/mips/bits/sigaction.h +++ b/libc/sysdeps/linux/mips/bits/sigaction.h @@ -23,37 +23,22 @@ #endif /* Structure describing the action to be taken when a signal arrives. */ -struct sigaction - { - /* Special flags. */ - unsigned int sa_flags; - - /* Signal handler. */ +struct sigaction { + unsigned sa_flags; #ifdef __USE_POSIX199309 - union - { - /* Used if SA_SIGINFO is not set. */ - __sighandler_t sa_handler; - /* Used if SA_SIGINFO is set. */ - void (*sa_sigaction) (int, siginfo_t *, void *); - } - __sigaction_handler; -# define sa_handler __sigaction_handler.sa_handler -# define sa_sigaction __sigaction_handler.sa_sigaction + union { + __sighandler_t sa_handler; + void (*sa_sigaction)(int, siginfo_t *, void *); + } __sigaction_handler; +# define sa_handler __sigaction_handler.sa_handler +# define sa_sigaction __sigaction_handler.sa_sigaction #else - __sighandler_t sa_handler; -#endif - /* Additional set of signals to be blocked. */ - __sigset_t sa_mask; - - /* The ABI says here are two unused ints following. */ - /* Restore handler. */ - void (*sa_restorer) (void); - -#if _MIPS_SZPTR < 64 - int sa_resv[1]; + __sighandler_t sa_handler; #endif - }; + sigset_t sa_mask; + void (*sa_restorer)(void); + /*int s_resv[1]; - reserved [deleted in uclibc] */ +}; /* Bits in `sa_flags'. */ /* Please note that some Linux kernels versions use different values for these diff --git a/libc/sysdeps/linux/mips/sigaction.c b/libc/sysdeps/linux/mips/sigaction.c index 7c933ffd5..f2d2747b5 100644 --- a/libc/sysdeps/linux/mips/sigaction.c +++ b/libc/sysdeps/linux/mips/sigaction.c @@ -29,113 +29,82 @@ extern __typeof(sigaction) __libc_sigaction; -#ifdef __NR_rt_sigaction - -/* Experimentally off - libc_hidden_proto(memcpy) */ -#if _MIPS_SIM != _ABIO32 +#ifdef __NR_rt_sigaction -# ifdef __NR_rt_sigreturn -static void restore_rt (void) __asm__ ("__restore_rt"); +# if _MIPS_SIM != _ABIO32 +# ifdef __NR_rt_sigreturn +static void restore_rt(void) __asm__ ("__restore_rt"); +# endif +# ifdef __NR_sigreturn +static void restore(void) __asm__ ("__restore"); +# endif # endif -# ifdef __NR_sigreturn -static void restore (void) __asm__ ("__restore"); + +/* 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) +{ +# if _MIPS_SIM != _ABIO32 + struct sigaction kact; + if (act) { + memcpy(&kact, act, sizeof(kact)); + kact.sa_restorer = &restore_rt; + act = &kact; + } # endif -#endif + + /* 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 + +extern void restore(void) __asm__ ("__restore") attribute_hidden; /* 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 _MIPS_SIM == _ABIO32 +# if _MIPS_SIM == _ABIO32 kact.sa_restorer = act->sa_restorer; -# else +# else kact.sa_restorer = &restore_rt; -# endif # 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)); - - if (oact && result >= 0) { + oact ? &koact : NULL); + if (result < 0) { + __set_errno(-result); + return -1; + } + if (oact) { 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 -extern void restore (void) __asm__ ("__restore") attribute_hidden; - -/* 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 _MIPS_SIM == _ABIO32 - kact.sa_restorer = act->sa_restorer; -# else - kact.sa_restorer = &restore_rt; -# endif -# endif - } - - result = __syscall_sigaction(sig, act ? &kact : NULL, - oact ? &koact : NULL); - - if (result < 0) { - __set_errno(-result); - return -1; - } - - if (oact) { - 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 + /* NOTE: Please think twice before making any changes to the bits of code below. GDB needs some intimate knowledge about it to recognize them as signal trampolines, and make backtraces through @@ -144,21 +113,21 @@ libc_hidden_weak(sigaction) If you ever feel the need to make any changes, please notify the appropriate GDB maintainer. */ -#define RESTORE(name, syscall) RESTORE2 (name, syscall) +#define RESTORE(name, syscall) RESTORE2(name, syscall) #define RESTORE2(name, syscall) \ -__asm__ ( \ - ".align 4\n" \ - "__" #name ":\n" \ - " li $2, " #syscall "\n" \ - " syscall\n" \ - ); +__asm__ ( \ + ".align 4\n" \ + "__" #name ":\n" \ + " li $2, " #syscall "\n" \ + " syscall\n" \ +); /* The return code for realtime-signals. */ #if _MIPS_SIM != _ABIO32 # ifdef __NR_rt_sigreturn -RESTORE (restore_rt, __NR_rt_sigreturn) +RESTORE(restore_rt, __NR_rt_sigreturn) # endif # ifdef __NR_sigreturn -RESTORE (restore, __NR_sigreturn) +RESTORE(restore, __NR_sigreturn) # endif #endif diff --git a/libc/sysdeps/linux/sparc/bits/sigaction.h b/libc/sysdeps/linux/sparc/bits/sigaction.h index ee4196764..be9bc028a 100644 --- a/libc/sysdeps/linux/sparc/bits/sigaction.h +++ b/libc/sysdeps/linux/sparc/bits/sigaction.h @@ -22,33 +22,21 @@ #endif /* Structure describing the action to be taken when a signal arrives. */ -struct sigaction - { - /* Signal handler. */ +struct sigaction { #ifdef __USE_POSIX199309 - union - { - /* Used if SA_SIGINFO is not set. */ - __sighandler_t sa_handler; - /* Used if SA_SIGINFO is set. */ - void (*sa_sigaction) (int, siginfo_t *, void *); - } - __sigaction_handler; -# define sa_handler __sigaction_handler.sa_handler -# define sa_sigaction __sigaction_handler.sa_sigaction + union { + __sighandler_t sa_handler; + void (*sa_sigaction)(int, siginfo_t *, void *); + } __sigaction_handler; +# define sa_handler __sigaction_handler.sa_handler +# define sa_sigaction __sigaction_handler.sa_sigaction #else - __sighandler_t sa_handler; + __sighandler_t sa_handler; #endif - - /* Additional set of signals to be blocked. */ - __sigset_t sa_mask; - - /* Special flags. */ - unsigned long sa_flags; - - /* Not used by Linux/Sparc yet. */ - void (*sa_restorer) (void); - }; + unsigned long sa_flags; + void (*sa_restorer)(void); + sigset_t sa_mask; +}; /* Bits in `sa_flags'. */ diff --git a/libc/sysdeps/linux/x86_64/sigaction.c b/libc/sysdeps/linux/x86_64/sigaction.c index 58466c8ef..d1adbc4be 100644 --- a/libc/sysdeps/linux/x86_64/sigaction.c +++ b/libc/sysdeps/linux/x86_64/sigaction.c @@ -25,9 +25,6 @@ #include -/* 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 /* We do not globally define the SA_RESTORER flag so do it here. */ @@ -35,64 +32,47 @@ extern __typeof(sigaction) __libc_sigaction; + #ifdef __NR_rt_sigaction + /* Using the hidden attribute here does not change the code but it helps to avoid warnings. */ -extern void restore_rt (void) __asm__ ("__restore_rt") attribute_hidden; -extern void restore (void) __asm__ ("__restore") attribute_hidden; - -/* Experimentally off - libc_hidden_proto(memcpy) */ +extern void restore_rt(void) __asm__ ("__restore_rt") attribute_hidden; +extern void restore(void) __asm__ ("__restore") attribute_hidden; /* 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 { - SIGSET_MIN_SIZE = sizeof(kact.sa_mask) < sizeof(act->sa_mask) - ? sizeof(kact.sa_mask) : sizeof(act->sa_mask) - }; + struct sigaction kact; 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 | SA_RESTORER; - + memcpy(&kact, act, sizeof(kact)); + kact.sa_flags |= SA_RESTORER; kact.sa_restorer = &restore_rt; + act = &kact; } - /* NB: kernel (as of 2.6.25) will return EINVAL - * if sizeof(kact.sa_mask) does not match kernel's sizeof(sigset_t) */ - result = INLINE_SYSCALL (rt_sigaction, 4, 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; - oact->sa_restorer = koact.sa_restorer; - } - return result; + * if sizeof(act->sa_mask) does not match kernel's sizeof(sigset_t) */ + return INLINE_SYSCALL(rt_sigaction, 4, sig, act, oact, sizeof(act->sa_mask)); } + #else -extern void restore (void) __asm__ ("__restore") attribute_hidden; +extern void restore(void) __asm__ ("__restore") attribute_hidden; /* 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; #ifdef SIGCANCEL if (sig == SIGCANCEL) { - __set_errno (EINVAL); + __set_errno(EINVAL); return -1; } #endif @@ -103,18 +83,16 @@ __libc_sigaction (int sig, const struct sigaction *act, struct sigaction *oact) kact.sa_flags = act->sa_flags | SA_RESTORER; kact.sa_restorer = &restore; } - - __asm__ __volatile__ ("syscall\n" - : "=a" (result) - : "0" (__NR_sigaction), "mr" (sig), - "c" (act ? &kact : 0), - "d" (oact ? &koact : 0)); - + __asm__ __volatile__ ( + "syscall\n" + : "=a" (result) + : "0" (__NR_sigaction), "mr" (sig), + "c" (act ? &kact : NULL), + "d" (oact ? &koact : NULL)); if (result < 0) { __set_errno(-result); return -1; } - if (oact) { oact->sa_handler = koact.k_sa_handler; oact->sa_mask.__val[0] = koact.sa_mask; @@ -123,14 +101,16 @@ __libc_sigaction (int sig, const struct sigaction *act, struct sigaction *oact) } return result; } + #endif + #ifndef LIBC_SIGACTION -/* libc_hidden_proto(sigaction) */ weak_alias(__libc_sigaction,sigaction) libc_hidden_weak(sigaction) #endif + /* NOTE: Please think twice before making any changes to the bits of code below. GDB needs some intimate knowledge about it to recognize them as signal trampolines, and make backtraces through @@ -139,18 +119,19 @@ libc_hidden_weak(sigaction) If you ever feel the need to make any changes, please notify the appropriate GDB maintainer. */ -#define RESTORE(name, syscall) RESTORE2 (name, syscall) -# define RESTORE2(name, syscall) \ -__asm__ ( \ - ".text\n" \ - "__" #name ":\n" \ - " movq $" #syscall ", %rax\n" \ - " syscall\n" \ - ); +#define RESTORE(name, syscall) RESTORE2(name, syscall) +#define RESTORE2(name, syscall) \ +__asm__ ( \ + ".text\n" \ + "__" #name ":\n" \ + " movq $" #syscall ", %rax\n" \ + " syscall\n" \ +); + #ifdef __NR_rt_sigaction /* The return code for realtime-signals. */ -RESTORE (restore_rt, __NR_rt_sigreturn) +RESTORE(restore_rt, __NR_rt_sigreturn) #endif #ifdef __NR_sigreturn -RESTORE (restore, __NR_sigreturn) +RESTORE(restore, __NR_sigreturn) #endif diff --git a/libc/sysdeps/linux/xtensa/sigaction.c b/libc/sysdeps/linux/xtensa/sigaction.c index 123cb5085..302d13305 100644 --- a/libc/sysdeps/linux/xtensa/sigaction.c +++ b/libc/sysdeps/linux/xtensa/sigaction.c @@ -15,52 +15,25 @@ #define SA_RESTORER 0x04000000 -extern void __default_sa_restorer (void); +extern void __default_sa_restorer(void); -/* Experimentally off - libc_hidden_proto(memcpy) */ - -int __libc_sigaction (int signum, const struct sigaction *act, +int __libc_sigaction(int sig, const struct sigaction *act, struct sigaction *oact) { - struct kernel_sigaction kact, koact; - int result; - enum { - 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; + struct sigaction kact; - if (kact.sa_flags & SA_RESTORER) { - kact.sa_restorer = act->sa_restorer; - } else { - kact.sa_restorer = __default_sa_restorer; - kact.sa_flags |= SA_RESTORER; - } + if (act && !(act->sa_flags & SA_RESTORER)) { + memcpy(&kact, act, sizeof(kact)); + kact.sa_restorer = __default_sa_restorer; + kact.sa_flags |= SA_RESTORER; + act = &kact; } - /* 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(signum, - 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; - oact->sa_restorer = koact.sa_restorer; - } - - return result; + * if sizeof(act->sa_mask) does not match kernel's sizeof(sigset_t) */ + return __syscall_rt_sigaction(sig, act, oact, sizeof(act->sa_mask)); } #ifndef LIBC_SIGACTION -libc_hidden_proto(sigaction) weak_alias(__libc_sigaction, sigaction) libc_hidden_weak(sigaction) #endif diff --git a/libpthread/linuxthreads/sysdeps/pthread/sigaction.c b/libpthread/linuxthreads/sysdeps/pthread/sigaction.c index 0a0a9e29f..2f2a85caf 100644 --- a/libpthread/linuxthreads/sysdeps/pthread/sigaction.c +++ b/libpthread/linuxthreads/sysdeps/pthread/sigaction.c @@ -17,6 +17,8 @@ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ +/* Somebody please explain what's going on here. --vda */ + /* This is tricky. GCC doesn't like #include_next in the primary source file and even if it did, the first #include_next is this exact file anyway. */ -- cgit v1.2.3