summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2008-12-15 09:29:33 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2008-12-15 09:29:33 +0000
commit885f507317b6c8576ba2e298c2249d27ea6f8404 (patch)
tree6d9a70d14c2f21d85538a023c7e2e863245c49e6
parent1cfb1a324798f6ed03e49813d8dfe6b28dfb9c4f (diff)
sigaction overhaul as described in docs/sigaction.txt
Run tested on i386.
-rw-r--r--docs/sigaction.txt6
-rw-r--r--include/signal.h33
-rw-r--r--libc/signal/sigaction.c61
-rw-r--r--libc/sysdeps/linux/alpha/bits/kernel_sigaction.h15
-rw-r--r--libc/sysdeps/linux/alpha/bits/sigaction.h33
-rw-r--r--libc/sysdeps/linux/arm/sigaction.c90
-rw-r--r--libc/sysdeps/linux/avr32/sigaction.c42
-rw-r--r--libc/sysdeps/linux/common/bits/kernel_sigaction.h67
-rw-r--r--libc/sysdeps/linux/common/bits/sigaction.h42
-rw-r--r--libc/sysdeps/linux/common/bits/sigset.h6
-rw-r--r--libc/sysdeps/linux/hppa/bits/kernel_sigaction.h15
-rw-r--r--libc/sysdeps/linux/hppa/bits/sigaction.h33
-rw-r--r--libc/sysdeps/linux/i386/sigaction.c158
-rw-r--r--libc/sysdeps/linux/ia64/bits/sigaction.h33
-rw-r--r--libc/sysdeps/linux/mips/bits/kernel_sigaction.h25
-rw-r--r--libc/sysdeps/linux/mips/bits/sigaction.h41
-rw-r--r--libc/sysdeps/linux/mips/sigaction.c137
-rw-r--r--libc/sysdeps/linux/sparc/bits/sigaction.h36
-rw-r--r--libc/sysdeps/linux/x86_64/sigaction.c89
-rw-r--r--libc/sysdeps/linux/xtensa/sigaction.c47
-rw-r--r--libpthread/linuxthreads/sysdeps/pthread/sigaction.c2
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 <bits/types.h>
#include <bits/signum.h>
+//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 <string.h>). */
-#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 <bits/pthreadtypes.h>
# include <bits/sigthread.h>
-#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 <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
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 <sgidefs.h>
-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 <bits/sigaction.h> directly; use <signal.h> 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 <sys/syscall.h>
-/* 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>
/* 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. */