[if you can't force yourself to read first part,
page down to "Proposed overhaul past 0.9.30" part]
All what you never wanted to know about sigaction(),
struct sigaction, and sigset_t.
Before vda started messing with sigset_t, struct sigaction
and sigaction() functions, things looked this way:
Structures
MIPS:
Ignoring bogus "#if defined(__mips__) ..." block in
libc/sysdeps/linux/common/bits/kernel_sigaction.h
and using
libc/sysdeps/linux/mips/bits/kernel_sigaction.h
as an authoritative source:
HAVE_SA_RESTORER is #defined
struct old_kernel_sigaction {
unsigned sa_flags;
sighandler_t k_sa_handler;
unsigned long sa_mask;
unsigned pad0[3]; /* reserved, keep size constant */
/* Abi says here follows reserved int[2] */
void (*sa_restorer)(void);
#if (_MIPS_SZPTR < 64)
/* For 32 bit code we have to pad struct sigaction to get
* constant size for the ABI */
int pad1[1]; /* reserved */
#endif
};
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 */
};
struct sigaction {
unsigned sa_flags;
sighandler_t sa_handler;
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];
#endif
};
IA64:
Has no old_sigaction. What a relief.
struct kernel_sigaction {
sighandler_t k_sa_handler;
unsigned long sa_flags;
sigset_t sa_mask;
};
struct sigaction {
sighandler_t sa_handler;
unsigned long sa_flags;
sigset_t sa_mask;
};
Alpha:
struct old_kernel_sigaction {
sighandler_t k_sa_handler;
unsigned long sa_mask;
unsigned sa_flags;
};
struct kernel_sigaction {
sighandler_t k_sa_handler;
unsigned sa_flags;
sigset_t sa_mask;
};
struct sigaction {
sighandler_t sa_handler;
sigset_t sa_mask;
unsigned sa_flags;
};
HPPA:
struct kernel_sigaction {
sighandler_t k_sa_handler;
unsigned long sa_flags;
sigset_t sa_mask;
};
struct sigaction {
sighandler_t sa_handler;
unsigned long sa_flags;
sigset_t sa_mask;
};
The rest, kernel side:
HAVE_SA_RESTORER #defined
struct old_kernel_sigaction {
sighandler_t k_sa_handler;
unsigned long sa_mask;
unsigned long sa_flags;
void (*sa_restorer)(void);
};
struct kernel_sigaction {
sighandler_t k_sa_handler;
unsigned long sa_flags;
void (*sa_restorer)(void);
sigset_t sa_mask;
};
On userspace side, Sparc has special struct sigaction:
struct sigaction {
sighandler_t sa_handler;
sigset_t sa_mask;
unsigned long sa_flags;
void (*sa_restorer)(void); /* Not used by Linux/Sparc */
};
And finally the rest has:
struct sigaction {
sighandler_t sa_handler;
sigset_t sa_mask;
int sa_flags;
void (*sa_restorer)(void);
};
Userspace sigset_t was uniformly defined as vector of longs
big enough to hold 1024 (!) bits - carried over from glibc.
Since the only arch whose struct kernel_sigaction contains sa_mask
not as a last member is MIPS, MIPS has special kernel_sigset_t,
which is an array of longs long enough for 128 bits.
Other arches still used userspace sigset_t in struct kernel_sigaction,
but it did not really matter because overlong kernel_sigaction
does not hurt in sigaction() [explained below].
On kernel side, all arches define _NSIG to 65 (meaning
there are 64 signals, 1..64) except MIPS, which define it to 129.
Functions
sigaction() [libc function] usually has two kernel_sigaction's
on stack and copy (userspace) struct sigaction members into
first one, executes syscall, then pulls out the result from
second one. This accomodates differences in layouts of structs.
The only typically present quirk is what to do with sa_restorer.
libc/sysdeps/linux/arm/sigaction.c
if HAVE_SA_RESTORER and (sa_flags & SA_RESTORER) is not set,
sets sa_restorer to
(flags & SA_SIGINFO) ? __default_rt_sa_restorer : __default_sa_restorer,
and sets SA_RESTORER,
otherwise passes it as-is. Which is kinda strange, because AFAICS
HAVE_SA_RESTORER is *not* defined for ARM.
libc/sysdeps/linux/i386/sigaction.c
Forcibly sets SA_RESTORER and sa_restorer:
kact.sa_flags = act->sa_flags | SA_RESTORER;
kact.sa_restorer = ((act->sa_flags & SA_SIGINFO) ? &restore_rt : &restore);
libc/sysdeps/linux/x86_64/sigaction.c
Forcibly sets SA_RESTORER and sa_restorer:
kact.sa_flags = act->sa_flags | SA_RESTORER;
kact.sa_restorer = &restore_rt;
libc/sysdeps/linux/mips/sigaction.c
# ifdef HAVE_SA_RESTORER
# if _MIPS_SIM == _ABIO32
kact.sa_restorer = act->sa_restorer;
# else
kact.sa_restorer = &restore_rt;
# endif
# endif
No confusion here, HAVE_SA_RESTORER is #defined for MIPS
libc/sysdeps/linux/avr32/sigaction.c
if (kact.sa_flags & SA_RESTORER) {
kact.sa_restorer = act->sa_restorer;
} else {
kact.sa_restorer = __default_rt_sa_restorer;
kact.sa_flags |= SA_RESTORER;
}
Does not check HAVE_SA_RESTORER, but avr32 falls
in "completely ordinary" category on both kernel and
userspace sides, and those have it defined.
libc/sysdeps/linux/xtensa/sigaction.c
if (kact.sa_flags & SA_RESTORER) {
kact.sa_restorer = act->sa_restorer;
} else {
kact.sa_restorer = __default_sa_restorer;
kact.sa_flags |= SA_RESTORER;
}
Thus, similar to avr32.
libc/signal/sigaction.c (i.e. the all other arches)
# ifdef HAVE_SA_RESTORER
kact.sa_restorer = act->sa_restorer;
# endif
Plain translation, just sa_restorer copy is protected
by HAVE_SA_RESTORER #define check. Looks like here
HAVE_SA_RESTORER will be undef'ed only for IA64,
Alpha an HPPA.
Proposed overhaul past 0.9.30
Since we can define libc-side structures at will:
make sigset_t and struct sigaction identical on kernel side and libc side
within each arch. If arches do not need special handling of sa_restorer,
then sigaction() can directly use passed struct sigaction as-is.
Otherwise, a copy is still needed, although sigaction() might have
just one struct kernel_sigaction on stack and use it both for passing
data to kernel and for receiving it back. Might save a few bytes.
To this effect:
* Make sigset_t size match kernel side on all arches.
This is easy since all arches have 64 signals and only MIPS has 128.
* Modify libc/sysdeps/linux/$ARCH/bits/sigaction.h
so that its struct sigaction matches kernel's. If sa_restorer
field is present in libc but is missing in kernel_sigaction,
add it at the bottom in order to not mess up kernel_sigaction layout.
* Modify libc/sysdeps/linux/$ARCH/sigaction.c
to implement the logic above. In "common" pseudo-arch
(libc/signal/sigaction.c file),
we would not even need to do any copying, as described above.
* Document discovered arch quirks while debugging this mess.
* Deal with old_kernel_sigaction later.
Patch is below. Result on i386:
text data bss dec hex filename
- 195 0 0 195 c3
libc/sysdeps/linux/i386/sigaction.os
+ 112 0 0 112 70
libc/sysdeps/linux/i386/sigaction.os
--
vda
diff -d -urpN uClibc.5/include/signal.h uClibc.6/include/signal.h
--- uClibc.5/include/signal.h 2008-12-13 16:05:18.000000000 +0100
+++ uClibc.6/include/signal.h 2008-12-13 23:45:25.000000000 +0100
@@ -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 __
#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 __a
#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
#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,
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 -d -urpN uClibc.5/libc/signal/sigaction.c uClibc.6/libc/signal/sigaction.c
--- uClibc.5/libc/signal/sigaction.c 2008-12-13 21:58:13.000000000 +0100
+++ uClibc.6/libc/signal/sigaction.c 2008-12-14 04:29:20.000000000 +0100
@@ -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
/* 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
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
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 -d -urpN uClibc.5/libc/sysdeps/linux/alpha/bits/kernel_sigaction.h
uClibc.6/libc/sysdeps/linux/alpha/bits/kernel_sigaction.h
--- uClibc.5/libc/sysdeps/linux/alpha/bits/kernel_sigaction.h 2008-12-13
22:05:13.000000000 +0100
+++ uClibc.6/libc/sysdeps/linux/alpha/bits/kernel_sigaction.h 2008-12-14
03:51:51.000000000 +0100
@@ -10,14 +10,10 @@ struct old_kernel_sigaction {
};
/* This is the sigaction structure from the Linux 2.1.68 kernel. */
+/* [struct kernel_sigaction was here] */
+/* [but it is identical to struct sigaction in uclibc] */
-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 -d -urpN uClibc.5/libc/sysdeps/linux/alpha/bits/sigaction.h
uClibc.6/libc/sysdeps/linux/alpha/bits/sigaction.h
--- uClibc.5/libc/sysdeps/linux/alpha/bits/sigaction.h 2008-12-13
16:05:36.000000000 +0100
+++ uClibc.6/libc/sysdeps/linux/alpha/bits/sigaction.h 2008-12-14
03:38:20.000000000 +0100
@@ -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 -d -urpN uClibc.5/libc/sysdeps/linux/arm/sigaction.c
uClibc.6/libc/sysdeps/linux/arm/sigaction.c
--- uClibc.5/libc/sysdeps/linux/arm/sigaction.c 2008-12-13 21:58:13.000000000
+0100
+++ uClibc.6/libc/sysdeps/linux/arm/sigaction.c 2008-12-14 04:28:58.000000000
+0100
@@ -34,52 +34,65 @@ extern __typeof(sigaction) __libc_sigact
/* 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) {
+ memcpy(&kact, act, sizeof(kact));
+# ifdef HAVE_SA_RESTORER
+ if (!(kact.sa_flags & SA_RESTORER)) {
+ kact.sa_restorer = choose_restorer(kact.sa_flags);
+ kact.sa_flags |= SA_RESTORER;
+ }
+# endif
+ 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;
@@ -88,46 +101,10 @@ int __libc_sigaction (int sig, const str
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 -d -urpN uClibc.5/libc/sysdeps/linux/avr32/sigaction.c
uClibc.6/libc/sysdeps/linux/avr32/sigaction.c
--- uClibc.5/libc/sysdeps/linux/avr32/sigaction.c 2008-12-13
21:58:13.000000000 +0100
+++ uClibc.6/libc/sysdeps/linux/avr32/sigaction.c 2008-12-14
04:29:07.000000000 +0100
@@ -14,54 +14,32 @@
#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
+ memcpy(&kact, act, sizeof(kact));
+ if (!(kact.sa_flags & SA_RESTORER)) {
kact.sa_restorer = __default_rt_sa_restorer;
- kact.sa_flags |= 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 -d -urpN uClibc.5/libc/sysdeps/linux/common/bits/kernel_sigaction.h
uClibc.6/libc/sysdeps/linux/common/bits/kernel_sigaction.h
--- uClibc.5/libc/sysdeps/linux/common/bits/kernel_sigaction.h 2008-12-13
22:05:09.000000000 +0100
+++ uClibc.6/libc/sysdeps/linux/common/bits/kernel_sigaction.h 2008-12-14
03:51:28.000000000 +0100
@@ -4,72 +4,39 @@
/* 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]; };
-#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__)
+#if 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;
-};
+/* [struct kernel_sigaction was here] */
+/* [but it is identical to struct sigaction in uclibc] */
#else
+#undef NO_OLD_SIGACTION
#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);
+ __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;
-};
+/* [struct kernel_sigaction was here] */
+/* [but it is identical to struct sigaction in uclibc] */
#endif
+
#ifndef NO_OLD_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 -d -urpN uClibc.5/libc/sysdeps/linux/common/bits/sigaction.h
uClibc.6/libc/sysdeps/linux/common/bits/sigaction.h
--- uClibc.5/libc/sysdeps/linux/common/bits/sigaction.h 2008-12-13
16:05:38.000000000 +0100
+++ uClibc.6/libc/sysdeps/linux/common/bits/sigaction.h 2008-12-14
03:50:51.000000000 +0100
@@ -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. */
- 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 -d -urpN uClibc.5/libc/sysdeps/linux/common/bits/sigset.h
uClibc.6/libc/sysdeps/linux/common/bits/sigset.h
--- uClibc.5/libc/sysdeps/linux/common/bits/sigset.h 2008-12-13
16:05:38.000000000 +0100
+++ uClibc.6/libc/sysdeps/linux/common/bits/sigset.h 2008-12-14
03:44:50.000000000 +0100
@@ -29,10 +29,10 @@ 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,
+ * apart from possible vestigial sa_restorer field tacked onto the end
+ * of userspace one, for the benefit of programs which (ab)use it.
*/
#if defined(__mips__)
# define _SIGSET_NWORDS (128 / (8 * sizeof (unsigned long)))
diff -d -urpN uClibc.5/libc/sysdeps/linux/hppa/bits/kernel_sigaction.h
uClibc.6/libc/sysdeps/linux/hppa/bits/kernel_sigaction.h
--- uClibc.5/libc/sysdeps/linux/hppa/bits/kernel_sigaction.h 2008-12-13
22:05:20.000000000 +0100
+++ uClibc.6/libc/sysdeps/linux/hppa/bits/kernel_sigaction.h 2008-12-14
03:51:39.000000000 +0100
@@ -13,14 +13,10 @@ struct old_kernel_sigaction {
};
/* This is the sigaction structure from the Linux 2.1.68 kernel. */
+/* [struct kernel_sigaction was here] */
+/* [but it is identical to struct sigaction in uclibc] */
-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 -d -urpN uClibc.5/libc/sysdeps/linux/hppa/bits/sigaction.h
uClibc.6/libc/sysdeps/linux/hppa/bits/sigaction.h
--- uClibc.5/libc/sysdeps/linux/hppa/bits/sigaction.h 2008-12-13
16:05:37.000000000 +0100
+++ uClibc.6/libc/sysdeps/linux/hppa/bits/sigaction.h 2008-12-14
03:32:44.000000000 +0100
@@ -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 -d -urpN uClibc.5/libc/sysdeps/linux/i386/sigaction.c
uClibc.6/libc/sysdeps/linux/i386/sigaction.c
--- uClibc.5/libc/sysdeps/linux/i386/sigaction.c 2008-12-13
21:58:13.000000000 +0100
+++ uClibc.6/libc/sysdeps/linux/i386/sigaction.c 2008-12-14
04:29:00.000000000 +0100
@@ -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" \
- );
+__asm__ ( \
+ ".text\n" \
+ "__" #name ":\n" \
+ " popl %eax\n" \
+ " movl $" #syscall ", %eax\n" \
+ " int $0x80\n" \
+);
-RESTORE (restore, __NR_sigreturn)
+RESTORE(restore, __NR_sigreturn)
#endif
diff -d -urpN uClibc.5/libc/sysdeps/linux/ia64/bits/sigaction.h
uClibc.6/libc/sysdeps/linux/ia64/bits/sigaction.h
--- uClibc.5/libc/sysdeps/linux/ia64/bits/sigaction.h 2008-12-13
16:05:43.000000000 +0100
+++ uClibc.6/libc/sysdeps/linux/ia64/bits/sigaction.h 2008-12-14
03:33:27.000000000 +0100
@@ -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 -d -urpN uClibc.5/libc/sysdeps/linux/mips/bits/kernel_sigaction.h
uClibc.6/libc/sysdeps/linux/mips/bits/kernel_sigaction.h
--- uClibc.5/libc/sysdeps/linux/mips/bits/kernel_sigaction.h 2008-12-13
22:05:16.000000000 +0100
+++ uClibc.6/libc/sysdeps/linux/mips/bits/kernel_sigaction.h 2008-12-14
03:51:46.000000000 +0100
@@ -24,25 +24,11 @@ struct old_kernel_sigaction {
#endif
};
-
-#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 */
-};
+/* [struct kernel_sigaction was here] */
+/* [but it is identical to struct sigaction in uclibc] */
-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 -d -urpN uClibc.5/libc/sysdeps/linux/mips/bits/sigaction.h
uClibc.6/libc/sysdeps/linux/mips/bits/sigaction.h
--- uClibc.5/libc/sysdeps/linux/mips/bits/sigaction.h 2008-12-13
16:05:43.000000000 +0100
+++ uClibc.6/libc/sysdeps/linux/mips/bits/sigaction.h 2008-12-14
03:36:57.000000000 +0100
@@ -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 -d -urpN uClibc.5/libc/sysdeps/linux/mips/sigaction.c
uClibc.6/libc/sysdeps/linux/mips/sigaction.c
--- uClibc.5/libc/sysdeps/linux/mips/sigaction.c 2008-12-13
21:58:13.000000000 +0100
+++ uClibc.6/libc/sysdeps/linux/mips/sigaction.c 2008-12-14
04:29:04.000000000 +0100
@@ -29,113 +29,91 @@
extern __typeof(sigaction) __libc_sigaction;
-#ifdef __NR_rt_sigaction
-/* Experimentally off - libc_hidden_proto(memcpy) */
+#ifdef __NR_rt_sigaction
#if _MIPS_SIM != _ABIO32
-
# ifdef __NR_rt_sigreturn
-static void restore_rt (void) __asm__ ("__restore_rt");
+static void restore_rt(void) __asm__ ("__restore_rt");
# endif
# ifdef __NR_sigreturn
-static void restore (void) __asm__ ("__restore");
+static void restore(void) __asm__ ("__restore");
# endif
#endif
/* 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;
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;
+ memcpy(&kact, act, sizeof(kact));
+ kact.sa_flags |= SA_RESTORER;
+ kact.sa_restorer = (act->sa_flags & SA_SIGINFO) ? &restore_rt :
&restore;
# ifdef HAVE_SA_RESTORER
-# if _MIPS_SIM == _ABIO32
- kact.sa_restorer = act->sa_restorer;
-# else
+# if _MIPS_SIM != _ABIO32
kact.sa_restorer = &restore_rt;
# endif
# endif
+ 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;
-# 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) */
+ 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;
- if (act) {
- kact.k_sa_handler = act->sa_handler;
- kact.sa_mask = act->sa_mask.__val[0];
- kact.sa_flags = act->sa_flags;
+ 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;
+ kact.sa_restorer = act->sa_restorer;
# else
- kact.sa_restorer = &restore_rt;
+ 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;
+ }
+ 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;
+ oact->sa_restorer = koact.sa_restorer;
# endif
- }
- return result;
+ }
+ 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 +122,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 -d -urpN uClibc.5/libc/sysdeps/linux/sparc/bits/sigaction.h
uClibc.6/libc/sysdeps/linux/sparc/bits/sigaction.h
--- uClibc.5/libc/sysdeps/linux/sparc/bits/sigaction.h 2008-12-13
16:05:44.000000000 +0100
+++ uClibc.6/libc/sysdeps/linux/sparc/bits/sigaction.h 2008-12-14
03:46:51.000000000 +0100
@@ -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 -d -urpN uClibc.5/libc/sysdeps/linux/x86_64/sigaction.c
uClibc.6/libc/sysdeps/linux/x86_64/sigaction.c
--- uClibc.5/libc/sysdeps/linux/x86_64/sigaction.c 2008-12-13
21:58:13.000000000 +0100
+++ uClibc.6/libc/sysdeps/linux/x86_64/sigaction.c 2008-12-14
04:29:09.000000000 +0100
@@ -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
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
}
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 -d -urpN uClibc.5/libc/sysdeps/linux/xtensa/sigaction.c
uClibc.6/libc/sysdeps/linux/xtensa/sigaction.c
--- uClibc.5/libc/sysdeps/linux/xtensa/sigaction.c 2008-12-13
21:58:13.000000000 +0100
+++ uClibc.6/libc/sysdeps/linux/xtensa/sigaction.c 2008-12-14
04:29:12.000000000 +0100
@@ -15,52 +15,27 @@
#define SA_RESTORER 0x04000000
-extern void __default_sa_restorer (void);
-
-/* Experimentally off - libc_hidden_proto(memcpy) */
+extern void __default_sa_restorer(void);
-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)
- };
+ 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 {
+ memcpy(&kact, act, sizeof(kact));
+ if (!(kact.sa_flags & SA_RESTORER)) {
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 -d -urpN uClibc.5/libpthread/linuxthreads/sysdeps/pthread/sigaction.c
uClibc.6/libpthread/linuxthreads/sysdeps/pthread/sigaction.c
--- uClibc.5/libpthread/linuxthreads/sysdeps/pthread/sigaction.c
2008-12-13 16:05:50.000000000 +0100
+++ uClibc.6/libpthread/linuxthreads/sysdeps/pthread/sigaction.c
2008-12-14 01:31:36.000000000 +0100
@@ -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. */
_______________________________________________
uClibc mailing list
[email protected]
http://busybox.net/cgi-bin/mailman/listinfo/uclibc