Browse Source

sigaction overhaul as described in docs/sigaction.txt
Run tested on i386.

Denis Vlasenko 15 years ago
parent
commit
885f507317

+ 5 - 1
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.

+ 22 - 11
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.  */

+ 13 - 48
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

+ 6 - 9
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

+ 12 - 21
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.  */

+ 29 - 61
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

+ 9 - 33
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

+ 14 - 53
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 */

+ 17 - 25
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.  */

+ 2 - 4
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)))

+ 6 - 9
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

+ 12 - 21
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'.  */
 

+ 65 - 93
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

+ 12 - 21
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.  */

+ 6 - 19
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

+ 13 - 28
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

+ 53 - 84
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

+ 12 - 24
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'.  */

+ 35 - 54
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

+ 10 - 37
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

+ 2 - 0
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.  */