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. --- libc/sysdeps/linux/mips/bits/kernel_sigaction.h | 25 ++--- libc/sysdeps/linux/mips/bits/sigaction.h | 41 +++---- libc/sysdeps/linux/mips/sigaction.c | 137 +++++++++--------------- 3 files changed, 72 insertions(+), 131 deletions(-) (limited to 'libc/sysdeps/linux/mips') 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 -- cgit v1.2.3