diff options
author | Elliott Hughes <enh@google.com> | 2013-10-16 22:27:54 -0700 |
---|---|---|
committer | Elliott Hughes <enh@google.com> | 2013-10-17 11:36:55 -0700 |
commit | c7e9b2331771e5e87c34a8ee3dc6cc41d35b02fe (patch) | |
tree | c04816a58f739d9f76c12a0f5acf1676eed6c89c /libc/include/signal.h | |
parent | f89f1eaa6071111c2ef584e97efb23f1b5dbdd2d (diff) | |
download | bionic-c7e9b2331771e5e87c34a8ee3dc6cc41d35b02fe.zip bionic-c7e9b2331771e5e87c34a8ee3dc6cc41d35b02fe.tar.gz bionic-c7e9b2331771e5e87c34a8ee3dc6cc41d35b02fe.tar.bz2 |
Fix sigaction(3) for 64-bit.
Also clean up <signal.h> and revert the hacks that were necessary
for 64-bit in linker/debugger.cpp until now.
Change-Id: I3b0554ca8a49ee1c97cda086ce2c1954ebc11892
Diffstat (limited to 'libc/include/signal.h')
-rw-r--r-- | libc/include/signal.h | 107 |
1 files changed, 42 insertions, 65 deletions
diff --git a/libc/include/signal.h b/libc/include/signal.h index e211ef7..5e74161 100644 --- a/libc/include/signal.h +++ b/libc/include/signal.h @@ -25,6 +25,7 @@ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ + #ifndef _SIGNAL_H_ #define _SIGNAL_H_ @@ -33,7 +34,18 @@ #include <limits.h> /* For LONG_BIT */ #include <string.h> /* For memset() */ #include <sys/types.h> -#include <asm/signal.h> + +#if defined(__LP64__) +/* For 64-bit, the kernel's struct sigaction doesn't match the POSIX one, + * so we need to expose our own and translate behind the scenes. */ +# define sigaction __kernel_sigaction +# include <asm/signal.h> +# undef sigaction +#else +/* For 32-bit, we're stuck with the definitions we already shipped, + * even though they contain a sigset_t that's too small. */ +# include <asm/signal.h> +#endif #define __ARCH_SI_UID_T __kernel_uid32_t #include <asm/siginfo.h> @@ -57,73 +69,37 @@ typedef int sig_atomic_t; extern const char* const sys_siglist[]; extern const char* const sys_signame[]; -static __inline__ int sigismember(const sigset_t* set, int signum) { - int bit = signum - 1; // Signal numbers start at 1, but bit positions start at 0. - const unsigned long* local_set = (const unsigned long*) set; - if (set == NULL || bit < 0 || bit >= (int) (8*sizeof(sigset_t))) { - errno = EINVAL; - return -1; - } - return (int) ((local_set[bit / LONG_BIT] >> (bit % LONG_BIT)) & 1); -} - -static __inline__ int sigaddset(sigset_t* set, int signum) { - int bit = signum - 1; // Signal numbers start at 1, but bit positions start at 0. - unsigned long* local_set = (unsigned long*) set; - if (set == NULL || bit < 0 || bit >= (int) (8*sizeof(sigset_t))) { - errno = EINVAL; - return -1; - } - local_set[bit / LONG_BIT] |= 1UL << (bit % LONG_BIT); - return 0; -} - -static __inline__ int sigdelset(sigset_t* set, int signum) { - int bit = signum - 1; // Signal numbers start at 1, but bit positions start at 0. - unsigned long* local_set = (unsigned long*) set; - if (set == NULL || bit < 0 || bit >= (int) (8*sizeof(sigset_t))) { - errno = EINVAL; - return -1; - } - local_set[bit / LONG_BIT] &= ~(1UL << (bit % LONG_BIT)); - return 0; -} - -static __inline__ int sigemptyset(sigset_t* set) { - if (set == NULL) { - errno = EINVAL; - return -1; - } - memset(set, 0, sizeof *set); - return 0; -} - -static __inline__ int sigfillset(sigset_t* set) { - if (set == NULL) { - errno = EINVAL; - return -1; - } - memset(set, ~0, sizeof *set); - return 0; -} - - -/* compatibility types */ -typedef void (*sig_t)(int); -typedef sig_t sighandler_t; - -/* differentiater between sysv and bsd behaviour 8*/ -extern __sighandler_t sysv_signal(int, __sighandler_t); -extern __sighandler_t bsd_signal(int, __sighandler_t); - -/* the default is bsd */ -static __inline__ __sighandler_t signal(int s, __sighandler_t f) -{ - return bsd_signal(s,f); -} +typedef __sighandler_t sig_t; /* BSD compatibility. */ +typedef __sighandler_t sighandler_t; /* glibc compatibility. */ + +#if __LP64__ + +struct sigaction { + unsigned int sa_flags; + union { + sighandler_t sa_handler; + void (*sa_sigaction)(int, struct siginfo*, void*); + }; + sigset_t sa_mask; + void (*sa_restorer)(void); +}; + +#endif extern int sigaction(int, const struct sigaction*, struct sigaction*); + +extern sighandler_t signal(int, sighandler_t); +extern sighandler_t bsd_signal(int, sighandler_t); +extern sighandler_t sysv_signal(int, sighandler_t); + extern int siginterrupt(int, int); + +extern int sigaddset(sigset_t*, int); +extern int sigdelset(sigset_t*, int); +extern int sigemptyset(sigset_t*); +extern int sigfillset(sigset_t*); +extern int sigismember(const sigset_t*, int); + extern int sigpending(sigset_t*) __nonnull((1)); extern int sigprocmask(int, const sigset_t*, sigset_t*); extern int sigsuspend(const sigset_t*) __nonnull((1)); @@ -132,6 +108,7 @@ extern int sigwait(const sigset_t*, int*) __nonnull((1, 2)); extern int raise(int); extern int kill(pid_t, int); extern int killpg(int, int); + extern int sigaltstack(const stack_t*, stack_t*); extern void psiginfo(const siginfo_t*, const char*); |