Browse Source

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

Denis Vlasenko 16 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.
 * 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/types.h>
 #include <bits/signum.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
 #if defined __USE_XOPEN || defined __USE_XOPEN2K
 # ifndef __pid_t_defined
 # ifndef __pid_t_defined
 typedef __pid_t pid_t;
 typedef __pid_t pid_t;
 #  define __pid_t_defined
 #  define __pid_t_defined
-#endif
-#ifdef __USE_XOPEN
 # endif
 # endif
 # ifndef __uid_t_defined
 # ifndef __uid_t_defined
 typedef __uid_t uid_t;
 typedef __uid_t uid_t;
@@ -79,10 +89,10 @@ typedef void (*__sighandler_t) (int);
    requested.  */
    requested.  */
 extern __sighandler_t __sysv_signal (int __sig, __sighandler_t __handler)
 extern __sighandler_t __sysv_signal (int __sig, __sighandler_t __handler)
      __THROW;
      __THROW;
-#ifdef __USE_GNU
+# ifdef __USE_GNU
 extern __sighandler_t sysv_signal (int __sig, __sighandler_t __handler)
 extern __sighandler_t sysv_signal (int __sig, __sighandler_t __handler)
      __THROW;
      __THROW;
-#endif
+# endif
 #endif /* __UCLIBC_HAS_OBSOLETE_SYSV_SIGNAL__ */
 #endif /* __UCLIBC_HAS_OBSOLETE_SYSV_SIGNAL__ */
 
 
 /* Set the handler for the signal SIG to HANDLER, returning the old
 /* 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
 #ifdef __USE_POSIX
 extern int kill (__pid_t __pid, int __sig) __THROW;
 extern int kill (__pid_t __pid, int __sig) __THROW;
 libc_hidden_proto(kill)
 libc_hidden_proto(kill)
-#endif /* Use POSIX.  */
+#endif
 
 
 #if defined __USE_BSD || defined __USE_XOPEN_EXTENDED
 #if defined __USE_BSD || defined __USE_XOPEN_EXTENDED
 /* Send SIG to all processes in process group PGRP.
 /* Send SIG to all processes in process group PGRP.
    If PGRP is zero, send SIG to all processes in
    If PGRP is zero, send SIG to all processes in
    the current process's process group.  */
    the current process's process group.  */
 extern int killpg (__pid_t __pgrp, int __sig) __THROW;
 extern int killpg (__pid_t __pgrp, int __sig) __THROW;
-#endif /* Use BSD || X/Open Unix.  */
+#endif
 
 
 __BEGIN_NAMESPACE_STD
 __BEGIN_NAMESPACE_STD
 /* Raise signal SIG, i.e., send SIG to yourself.  */
 /* Raise signal SIG, i.e., send SIG to yourself.  */
@@ -195,8 +205,9 @@ extern int siggetmask (void) __THROW __attribute_deprecated__;
 #endif /* Use BSD.  */
 #endif /* Use BSD.  */
 
 
 
 
+/* Biggest signal number + 1 (including real-time signals).  */
 #ifdef __USE_MISC
 #ifdef __USE_MISC
-# define NSIG	_NSIG
+# define NSIG  _NSIG
 #endif
 #endif
 
 
 #ifdef __USE_GNU
 #ifdef __USE_GNU
@@ -316,12 +327,12 @@ extern int sigqueue (__pid_t __pid, int __sig, __const union sigval __val)
 
 
 #ifdef __USE_BSD
 #ifdef __USE_BSD
 
 
-#ifdef __UCLIBC_HAS_SYS_SIGLIST__
+# ifdef __UCLIBC_HAS_SYS_SIGLIST__
 /* Names of the signals.  This variable exists only for compatibility.
 /* Names of the signals.  This variable exists only for compatibility.
    Use `strsignal' instead (see <string.h>).  */
    Use `strsignal' instead (see <string.h>).  */
-#define _sys_siglist sys_siglist
+#  define _sys_siglist sys_siglist
 extern __const char *__const sys_siglist[_NSIG];
 extern __const char *__const sys_siglist[_NSIG];
-#endif /* __UCLIBC_HAS_SYS_SIGLIST__ */
+# endif
 
 
 /* Structure passed to `sigvec'.  */
 /* Structure passed to `sigvec'.  */
 struct sigvec
 struct sigvec
@@ -404,7 +415,7 @@ extern __sighandler_t sigset (int __sig, __sighandler_t __disp) __THROW;
    be defined here.  */
    be defined here.  */
 # include <bits/pthreadtypes.h>
 # include <bits/pthreadtypes.h>
 # include <bits/sigthread.h>
 # include <bits/sigthread.h>
-#endif /* use Unix98 */
+#endif
 
 
 /* The following functions are used internally in the C library and in
 /* The following functions are used internally in the C library and in
    other code which need deep insights.  */
    other code which need deep insights.  */

+ 13 - 48
libc/signal/sigaction.c

@@ -20,62 +20,30 @@
 #include <errno.h>
 #include <errno.h>
 #include <signal.h>
 #include <signal.h>
 #include <string.h>
 #include <string.h>
-
 #include <sys/syscall.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>
 #include <bits/kernel_sigaction.h>
 
 
 #ifndef LIBC_SIGACTION
 #ifndef LIBC_SIGACTION
 extern __typeof(sigaction) __libc_sigaction;
 extern __typeof(sigaction) __libc_sigaction;
 #endif
 #endif
 
 
+
 #if defined __NR_rt_sigaction
 #if defined __NR_rt_sigaction
 
 
 /* If ACT is not NULL, change the action for SIG to *ACT.
 /* 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.  */
    If OACT is not NULL, put the old action for SIG in *OACT.  */
 int
 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
 	/* NB: kernel (as of 2.6.25) will return EINVAL
-	 * if sizeof(kact.sa_mask) does not match kernel's sizeof(sigset_t) */
+	 * if sizeof(act->sa_mask) does not match kernel's sizeof(sigset_t).
-	result = __syscall_rt_sigaction(sig,
+	 * Try to catch this problem at uclibc build time:  */
-			act ? &kact : NULL,
+	struct BUG_sigset_size {
-			oact ? &koact : NULL,
+		int BUG_sigset_size
-			sizeof(kact.sa_mask));
+			[sizeof(act->sa_mask) != _NSIG / 8 ? 1 : -1];
-
+	};
-	if (oact && result >= 0) {
+	return __syscall_rt_sigaction(sig, act, oact, sizeof(act->sa_mask));
-		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;
 }
 }
 
 
 #else
 #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 ACT is not NULL, change the action for SIG to *ACT.
    If OACT is not NULL, put the old action for SIG in *OACT.  */
    If OACT is not NULL, put the old action for SIG in *OACT.  */
 int
 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;
 	int result;
 	struct old_kernel_sigaction kact, koact;
 	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;
 		kact.sa_restorer = act->sa_restorer;
 # endif
 # endif
 	}
 	}
-
 	result = __syscall_sigaction(sig,
 	result = __syscall_sigaction(sig,
-			       act ? &kact : NULL,
+			act ? &kact : NULL,
-			       oact ? &koact : NULL);
+			oact ? &koact : NULL);
-
 	if (oact && result >= 0) {
 	if (oact && result >= 0) {
 		oact->sa_handler = koact.k_sa_handler;
 		oact->sa_handler = koact.k_sa_handler;
 		oact->sa_mask.__val[0] = koact.sa_mask;
 		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;
 		oact->sa_restorer = koact.sa_restorer;
 # endif
 # endif
 	}
 	}
-
 	return result;
 	return result;
 }
 }
 
 
 #endif
 #endif
 
 
+
 #ifndef LIBC_SIGACTION
 #ifndef LIBC_SIGACTION
-/* libc_hidden_proto(sigaction) */
 weak_alias(__libc_sigaction,sigaction)
 weak_alias(__libc_sigaction,sigaction)
 libc_hidden_weak(sigaction)
 libc_hidden_weak(sigaction)
 #endif
 #endif

+ 6 - 9
libc/sysdeps/linux/alpha/bits/kernel_sigaction.h

@@ -9,15 +9,12 @@ struct old_kernel_sigaction {
 	unsigned int sa_flags;
 	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 {
+extern int __syscall_rt_sigaction (int, const struct sigaction *,
-	__sighandler_t k_sa_handler;
+	struct sigaction *, size_t) attribute_hidden;
-	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;
 
 
 #endif
 #endif

+ 12 - 21
libc/sysdeps/linux/alpha/bits/sigaction.h

@@ -22,30 +22,21 @@
 #endif
 #endif
 
 
 /* Structure describing the action to be taken when a signal arrives.  */
 /* Structure describing the action to be taken when a signal arrives.  */
-struct sigaction
+struct sigaction {
-  {
-    /* Signal handler.  */
 #ifdef __USE_POSIX199309
 #ifdef __USE_POSIX199309
-    union
+	union {
-      {
+		__sighandler_t sa_handler;
-	/* Used if SA_SIGINFO is not set.  */
+		void (*sa_sigaction)(int, siginfo_t *, void *);
-	__sighandler_t sa_handler;
+	} __sigaction_handler;
-	/* Used if SA_SIGINFO is set.  */
+# define sa_handler     __sigaction_handler.sa_handler
-	void (*sa_sigaction) (int, siginfo_t *, void *);
+# define sa_sigaction   __sigaction_handler.sa_sigaction
-      }
-    __sigaction_handler;
-# define sa_handler	__sigaction_handler.sa_handler
-# define sa_sigaction	__sigaction_handler.sa_sigaction
 #else
 #else
-    __sighandler_t sa_handler;
+	__sighandler_t  sa_handler;
 #endif
 #endif
-
+	unsigned        sa_flags;
-    /* Additional set of signals to be blocked.  */
+	sigset_t        sa_mask;
-    __sigset_t sa_mask;
+	/* Alpha has no sa_restorer field.  */
-
+};
-    /* Special flags.  */
-    unsigned int sa_flags;
-  };
 
 
 /* Bits in `sa_flags'.  */
 /* Bits in `sa_flags'.  */
 #define	SA_NOCLDSTOP  0x00000004 /* Don't send SIGCHLD when children stop.  */
 #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.  */
 /* When RT signals are in use we need to use a different return stub.  */
 #ifdef __NR_rt_sigreturn
 #ifdef __NR_rt_sigreturn
 #define choose_restorer(flags)					\
 #define choose_restorer(flags)					\
-  (flags & SA_SIGINFO) ? __default_rt_sa_restorer		\
+	(flags & SA_SIGINFO) ? __default_rt_sa_restorer		\
-  : __default_sa_restorer
+	: __default_sa_restorer
 #else
 #else
 #define choose_restorer(flags)					\
 #define choose_restorer(flags)					\
-  __default_sa_restorer
+	__default_sa_restorer
 #endif
 #endif
 
 
+
 #ifdef __NR_rt_sigaction
 #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 ACT is not NULL, change the action for SIG to *ACT.
    If OACT is not NULL, put the old action for SIG in *OACT.  */
    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;
 	int result;
-	struct kernel_sigaction kact, koact;
+	struct old_kernel_sigaction kact, koact;
-	enum {
-		SIGSET_MIN_SIZE = sizeof(kact.sa_mask) < sizeof(act->sa_mask)
-				? sizeof(kact.sa_mask) : sizeof(act->sa_mask)
-	};
 
 
 	if (act) {
 	if (act) {
 		kact.k_sa_handler = act->sa_handler;
 		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;
 		kact.sa_flags = act->sa_flags;
-# ifdef HAVE_SA_RESTORER
 		if (kact.sa_flags & SA_RESTORER) {
 		if (kact.sa_flags & SA_RESTORER) {
 			kact.sa_restorer = act->sa_restorer;
 			kact.sa_restorer = act->sa_restorer;
 		} else {
 		} else {
-			kact.sa_restorer = choose_restorer (kact.sa_flags);
+			kact.sa_restorer = choose_restorer(kact.sa_flags);
 			kact.sa_flags |= SA_RESTORER;
 			kact.sa_flags |= SA_RESTORER;
 		}
 		}
-# endif
 	}
 	}
-
+	result = __syscall_sigaction(sig,
-	/* 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,
 			act ? &kact : NULL,
-			oact ? &koact : NULL,
+			oact ? &koact : NULL);
-			sizeof(kact.sa_mask));
-
 	if (oact && result >= 0) {
 	if (oact && result >= 0) {
 		oact->sa_handler = koact.k_sa_handler;
 		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;
 		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;
 }
 }
 
 
-
-#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
 #endif
 
 
+
 #ifndef LIBC_SIGACTION
 #ifndef LIBC_SIGACTION
-/* libc_hidden_proto(sigaction) */
 weak_alias(__libc_sigaction,sigaction)
 weak_alias(__libc_sigaction,sigaction)
 libc_hidden_weak(sigaction)
 libc_hidden_weak(sigaction)
 #endif
 #endif

+ 9 - 33
libc/sysdeps/linux/avr32/sigaction.c

@@ -14,54 +14,30 @@
 #define SA_RESTORER	0x04000000
 #define SA_RESTORER	0x04000000
 extern void __default_rt_sa_restorer(void);
 extern void __default_rt_sa_restorer(void);
 
 
-/* Experimentally off - libc_hidden_proto(memcpy) */
-
 extern __typeof(sigaction) __libc_sigaction;
 extern __typeof(sigaction) __libc_sigaction;
 
 
 /*
 /*
  * If act is not NULL, change the action for sig to *act.
  * 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.
  * If oact is not NULL, put the old action for sig in *oact.
  */
  */
-int __libc_sigaction(int signum, const struct sigaction *act,
+int __libc_sigaction(int sig, const struct sigaction *act,
-		     struct sigaction *oldact)
+		     struct sigaction *oact)
 {
 {
-	struct kernel_sigaction kact, koact;
+	struct sigaction kact;
-	int result;
-	enum {
-		SIGSET_MIN_SIZE = sizeof(kact.sa_mask) < sizeof(act->sa_mask)
-				? sizeof(kact.sa_mask) : sizeof(act->sa_mask)
-	};
 
 
-	if (act) {
+	if (act && !(act->sa_flags & SA_RESTORER)) {
-		kact.k_sa_handler = act->sa_handler;
+		memcpy(&kact, act, sizeof(kact));
-		memcpy(&kact.sa_mask, &act->sa_mask, SIGSET_MIN_SIZE);
+		kact.sa_restorer = __default_rt_sa_restorer;
-		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;
 		kact.sa_flags |= SA_RESTORER;
 		kact.sa_flags |= SA_RESTORER;
+		act = &kact;
 	}
 	}
 
 
 	/* NB: kernel (as of 2.6.25) will return EINVAL
 	/* NB: kernel (as of 2.6.25) will return EINVAL
-	 * if sizeof(kact.sa_mask) does not match kernel's sizeof(sigset_t) */
+	 * if sizeof(act->sa_mask) does not match kernel's sizeof(sigset_t) */
-	result = __syscall_rt_sigaction(signum,
+	return __syscall_rt_sigaction(sig, act, oact, sizeof(act->sa_mask));
-			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;
 }
 }
 
 
 #ifndef LIBC_SIGACTION
 #ifndef LIBC_SIGACTION
-/* libc_hidden_proto(sigaction) */
 weak_alias(__libc_sigaction, sigaction)
 weak_alias(__libc_sigaction, sigaction)
 libc_hidden_weak(sigaction)
 libc_hidden_weak(sigaction)
 #endif
 #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
 /* This file provides whatever this particular arch's kernel thinks
  * the sigaction struct should look like... */
  * the sigaction struct should look like... */
 
 
-#undef NO_OLD_SIGACTION
 
 
-#if defined(__mips__)
+#if defined(__ia64__)
-/* 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
 #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
 #else
 
 
 #define HAVE_SA_RESTORER
 #define HAVE_SA_RESTORER
 /* This is the sigaction structure from the Linux 2.1.20 kernel.  */
 /* This is the sigaction structure from the Linux 2.1.20 kernel.  */
 struct old_kernel_sigaction {
 struct old_kernel_sigaction {
-    __sighandler_t k_sa_handler;
+	__sighandler_t k_sa_handler;
-    unsigned long sa_mask;
+	unsigned long sa_mask;
-    unsigned long sa_flags;
+	unsigned long sa_flags;
-    void (*sa_restorer) (void);
+	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;
 };
 };
+/* In uclibc, userspace struct sigaction is identical to
+ * "new" struct kernel_sigaction (one from the Linux 2.1.68 kernel).
+ * See sigaction.h
+ */
 
 
-#endif
+extern int __syscall_sigaction(int, const struct old_kernel_sigaction *,
-
-#ifndef NO_OLD_SIGACTION
-extern int __syscall_sigaction (int, const struct old_kernel_sigaction *,
 	struct old_kernel_sigaction *) attribute_hidden;
 	struct old_kernel_sigaction *) attribute_hidden;
+
 #endif
 #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 */
 #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."
 # error "Never include <bits/sigaction.h> directly; use <signal.h> instead."
 #endif
 #endif
 
 
-/* Structure describing the action to be taken when a signal arrives.  */
+/* Structure describing the action to be taken when a signal arrives.
-struct sigaction
+ * In uclibc, it is identical to "new" struct kernel_sigaction
-  {
+ * (one from the Linux 2.1.68 kernel).
-    /* Signal handler.  */
+ * This minimizes amount of translation in sigaction().
+ */
+struct sigaction {
 #ifdef __USE_POSIX199309
 #ifdef __USE_POSIX199309
-    union
+	union {
-      {
+		__sighandler_t sa_handler;
-	/* Used if SA_SIGINFO is not set.  */
+		void (*sa_sigaction)(int, siginfo_t *, void *);
-	__sighandler_t sa_handler;
+	} __sigaction_handler;
-	/* Used if SA_SIGINFO is set.  */
+# define sa_handler     __sigaction_handler.sa_handler
-	void (*sa_sigaction) (int, siginfo_t *, void *);
+# define sa_sigaction   __sigaction_handler.sa_sigaction
-      }
-    __sigaction_handler;
-# define sa_handler	__sigaction_handler.sa_handler
-# define sa_sigaction	__sigaction_handler.sa_sigaction
 #else
 #else
-    __sighandler_t sa_handler;
+	__sighandler_t  sa_handler;
 #endif
 #endif
-
+	unsigned long   sa_flags;
-    /* Additional set of signals to be blocked.  */
+	void            (*sa_restorer)(void);
-    __sigset_t sa_mask;
+	sigset_t        sa_mask;
-
+};
-    /* Special flags.  */
-    int sa_flags;
-
-    /* Restore handler.  */
-    void (*sa_restorer) (void);
-  };
 
 
 /* Bits in `sa_flags'.  */
 /* Bits in `sa_flags'.  */
 #define	SA_NOCLDSTOP  1		 /* Don't send SIGCHLD when children stop.  */
 #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,
  * where they might have (or had in the past) 32 signals only,
  * I hope it's irrelevant now.
  * I hope it's irrelevant now.
  * Signal 0 does not exist, so we have signals 1..64, not 0..63.
  * Signal 0 does not exist, so we have signals 1..64, not 0..63.
- * Note that struct sigaction has embedded sigset_t,
+ * In uclibc, kernel and userspace sigset_t is always the same.
- * and this necessitates translation in sigaction()
+ * BTW, struct sigaction is also the same on kernel and userspace side.
- * to convert it to struct kernel_sigaction.
- * See libc/.../sigaction.c, libc/.../kernel_sigaction.h
  */
  */
 #if defined(__mips__)
 #if defined(__mips__)
 # define _SIGSET_NWORDS	(128 / (8 * sizeof (unsigned long)))
 # 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;
 	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 {
+extern int __syscall_rt_sigaction (int, const struct sigaction *,
-	__sighandler_t k_sa_handler;
+	struct sigaction *, size_t) attribute_hidden;
-	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;
 
 
 #endif
 #endif

+ 12 - 21
libc/sysdeps/linux/hppa/bits/sigaction.h

@@ -22,30 +22,21 @@
 #endif
 #endif
 
 
 /* Structure describing the action to be taken when a signal arrives.  */
 /* Structure describing the action to be taken when a signal arrives.  */
-struct sigaction
+struct sigaction {
-  {
-    /* Signal handler.  */
 #ifdef __USE_POSIX199309
 #ifdef __USE_POSIX199309
-    union
+	union {
-      {
+		__sighandler_t sa_handler;
-	/* Used if SA_SIGINFO is not set.  */
+		void (*sa_sigaction)(int, siginfo_t *, void *);
-	__sighandler_t sa_handler;
+	} __sigaction_handler;
-	/* Used if SA_SIGINFO is set.  */
+# define sa_handler     __sigaction_handler.sa_handler
-	void (*sa_sigaction) (int, siginfo_t *, void *);
+# define sa_sigaction   __sigaction_handler.sa_sigaction
-      }
-    __sigaction_handler;
-# define sa_handler	__sigaction_handler.sa_handler
-# define sa_sigaction	__sigaction_handler.sa_sigaction
 #else
 #else
-    __sighandler_t sa_handler;
+	__sighandler_t  sa_handler;
 #endif
 #endif
-
+	unsigned long   sa_flags;
-    /* Special flags.  */
+	sigset_t        sa_mask;
-    unsigned long int sa_flags;
+	/* HPPA has no sa_restorer field.  */
-
+};
-    /* Additional set of signals to be blocked.  */
-    __sigset_t sa_mask;
-  };
 
 
 /* Bits in `sa_flags'.  */
 /* Bits in `sa_flags'.  */
 
 

+ 65 - 93
libc/sysdeps/linux/i386/sigaction.c

@@ -29,115 +29,89 @@
 
 
 extern __typeof(sigaction) __libc_sigaction;
 extern __typeof(sigaction) __libc_sigaction;
 
 
+
 #if defined __NR_rt_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_rt(void) __asm__ ("__restore_rt") attribute_hidden;
-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 ACT is not NULL, change the action for SIG to *ACT.
    If OACT is not NULL, put the old action for SIG in *OACT.  */
    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 sigaction kact;
-	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)
-	};
 
 
 #ifdef SIGCANCEL
 #ifdef SIGCANCEL
 	if (sig == SIGCANCEL) {
 	if (sig == SIGCANCEL) {
-		__set_errno (EINVAL);
+		__set_errno(EINVAL);
 		return -1;
 		return -1;
 	}
 	}
 #endif
 #endif
-
 	if (act) {
 	if (act) {
-		kact.k_sa_handler = act->sa_handler;
+		memcpy(&kact, act, sizeof(kact));
-		memcpy (&kact.sa_mask, &act->sa_mask, SIGSET_MIN_SIZE);
+		kact.sa_flags |= SA_RESTORER;
-		kact.sa_flags = act->sa_flags;
+		kact.sa_restorer = (act->sa_flags & SA_SIGINFO) ? &restore_rt : &restore;
-
+		act = &kact;
-		kact.sa_flags = act->sa_flags | SA_RESTORER;
-		kact.sa_restorer = ((act->sa_flags & SA_SIGINFO)
-			? &restore_rt : &restore);
 	}
 	}
-
 	/* NB: kernel (as of 2.6.25) will return EINVAL
 	/* NB: kernel (as of 2.6.25) will return EINVAL
-	 * if sizeof(kact.sa_mask) does not match kernel's sizeof(sigset_t) */
+	 * if sizeof(act->sa_mask) does not match kernel's sizeof(sigset_t) */
-	result = __syscall_rt_sigaction(sig,
+	return __syscall_rt_sigaction(sig, act, oact, sizeof(act->sa_mask));
-			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;
 }
 }
 
 
-
 #else
 #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 ACT is not NULL, change the action for SIG to *ACT.
    If OACT is not NULL, put the old action for SIG in *OACT.  */
    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;
+	int result;
-    struct old_kernel_sigaction kact, koact;
+	struct old_kernel_sigaction kact, koact;
 
 
 #ifdef SIGCANCEL
 #ifdef SIGCANCEL
-    if (sig == SIGCANCEL) {
+	if (sig == SIGCANCEL) {
-	__set_errno (EINVAL);
+		__set_errno(EINVAL);
-	return -1;
+		return -1;
-    }
+	}
 #endif
 #endif
-
+	if (act) {
-    if (act) {
+		kact.k_sa_handler = act->sa_handler;
-	kact.k_sa_handler = act->sa_handler;
+		kact.sa_mask = act->sa_mask.__val[0];
-	kact.sa_mask = act->sa_mask.__val[0];
+		kact.sa_flags = act->sa_flags | SA_RESTORER;
-	kact.sa_flags = act->sa_flags | SA_RESTORER;
+		kact.sa_restorer = &restore;
-	kact.sa_restorer = &restore;
+	}
-    }
+	__asm__ __volatile__ (
-
+		"	pushl	%%ebx\n"
-    __asm__ __volatile__ ("pushl %%ebx\n"
+		"	movl	%3, %%ebx\n"
-	    "movl %3, %%ebx\n"
+		"	int	$0x80\n"
-	    "int $0x80\n"
+		"	popl	%%ebx\n"
-	    "popl %%ebx"
+		: "=a" (result), "=m" (koact)
-	    : "=a" (result), "=m" (koact)
+		: "0" (__NR_sigaction), "r" (sig), "m" (kact),
-	    : "0" (__NR_sigaction), "r" (sig), "m" (kact),
+		  "c" (act ? &kact : NULL),
-	    "c" (act ? &kact : 0),
+		  "d" (oact ? &koact : NULL));
-	    "d" (oact ? &koact : 0));
+	if (result < 0) {
-
+		__set_errno(-result);
-    if (result < 0) {
+		return -1;
-	__set_errno(-result);
+	}
-	return -1;
+	if (oact) {
-    }
+		oact->sa_handler = koact.k_sa_handler;
-
+		oact->sa_mask.__val[0] = koact.sa_mask;
-    if (oact) {
+		oact->sa_flags = koact.sa_flags;
-	oact->sa_handler = koact.k_sa_handler;
+		oact->sa_restorer = koact.sa_restorer;
-	oact->sa_mask.__val[0] = koact.sa_mask;
+	}
-	oact->sa_flags = koact.sa_flags;
+	return result;
-	oact->sa_restorer = koact.sa_restorer;
-    }
-    return result;
 }
 }
 
 
 #endif
 #endif
 
 
+
 #ifndef LIBC_SIGACTION
 #ifndef LIBC_SIGACTION
-/* libc_hidden_proto(sigaction) */
 weak_alias(__libc_sigaction,sigaction)
 weak_alias(__libc_sigaction,sigaction)
 libc_hidden_weak(sigaction)
 libc_hidden_weak(sigaction)
 #endif
 #endif
 
 
 
 
-
-
 /* NOTE: Please think twice before making any changes to the bits of
 /* NOTE: Please think twice before making any changes to the bits of
    code below.  GDB needs some intimate knowledge about it to
    code below.  GDB needs some intimate knowledge about it to
    recognize them as signal trampolines, and make backtraces through
    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
    If you ever feel the need to make any changes, please notify the
    appropriate GDB maintainer.  */
    appropriate GDB maintainer.  */
 
 
-#define RESTORE(name, syscall) RESTORE2 (name, syscall)
+#define RESTORE(name, syscall) RESTORE2(name, syscall)
 #define RESTORE2(name, syscall) \
 #define RESTORE2(name, syscall) \
-__asm__						\
+__asm__	(						\
-  (						\
+	".text\n"					\
-   ".text\n"					\
+	"__" #name ":\n"				\
-   "__" #name ":\n"				\
+	"	movl	$" #syscall ", %eax\n"		\
-   "	movl $" #syscall ", %eax\n"		\
+	"	int	$0x80\n"			\
-   "	int  $0x80"				\
+);
-   );
 
 
 #ifdef __NR_rt_sigaction
 #ifdef __NR_rt_sigaction
 /* The return code for realtime-signals.  */
 /* The return code for realtime-signals.  */
-RESTORE (restore_rt, __NR_rt_sigreturn)
+RESTORE(restore_rt, __NR_rt_sigreturn)
 #endif
 #endif
 
 
 #ifdef __NR_sigreturn
 #ifdef __NR_sigreturn
 /* For the boring old signals.  */
 /* For the boring old signals.  */
 # undef RESTORE2
 # undef RESTORE2
 # define RESTORE2(name, syscall) \
 # define RESTORE2(name, syscall) \
-__asm__						\
+__asm__ (						\
-  (						\
+	".text\n"					\
-   ".text\n"					\
+	"__" #name ":\n"				\
-   "__" #name ":\n"				\
+	"	popl	%eax\n"				\
-   "	popl %eax\n"				\
+	"	movl	$" #syscall ", %eax\n"		\
-   "	movl $" #syscall ", %eax\n"		\
+	"	int	$0x80\n"			\
-   "	int  $0x80"				\
+);
-   );
+
-
+RESTORE(restore, __NR_sigreturn)
-RESTORE (restore, __NR_sigreturn)
 #endif
 #endif

+ 12 - 21
libc/sysdeps/linux/ia64/bits/sigaction.h

@@ -22,30 +22,21 @@
 #endif
 #endif
 
 
 /* Structure describing the action to be taken when a signal arrives.  */
 /* Structure describing the action to be taken when a signal arrives.  */
-struct sigaction
+struct sigaction {
-  {
-    /* Signal handler.  */
 #ifdef __USE_POSIX199309
 #ifdef __USE_POSIX199309
-    union
+	union {
-      {
+		__sighandler_t sa_handler;
-	/* Used if SA_SIGINFO is not set.  */
+		void (*sa_sigaction)(int, siginfo_t *, void *);
-	__sighandler_t sa_handler;
+	} __sigaction_handler;
-	/* Used if SA_SIGINFO is set.  */
+# define sa_handler     __sigaction_handler.sa_handler
-	void (*sa_sigaction) (int, siginfo_t *, void *);
+# define sa_sigaction   __sigaction_handler.sa_sigaction
-      }
-    __sigaction_handler;
-# define sa_handler	__sigaction_handler.sa_handler
-# define sa_sigaction	__sigaction_handler.sa_sigaction
 #else
 #else
-    __sighandler_t sa_handler;
+	__sighandler_t  sa_handler;
 #endif
 #endif
-
+	unsigned long   sa_flags;
-    /* Special flags.  */
+	sigset_t        sa_mask;
-    unsigned long int sa_flags;
+	/* IA64 has no sa_restorer field.  */
-
+};
-    /* Additional set of signals to be blocked.  */
-    __sigset_t sa_mask;
-  };
 
 
 /* Bits in `sa_flags'.  */
 /* Bits in `sa_flags'.  */
 #define SA_NOCLDSTOP  0x00000001 /* Don't send SIGCHLD when children stop.  */
 #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
 #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
+extern int __syscall_rt_sigaction (int, const struct sigaction *,
-#define _KERNEL_NSIG_BPW       _MIPS_SZLONG
+	struct sigaction *, size_t) attribute_hidden;
-#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;
 
 
 #endif
 #endif

+ 13 - 28
libc/sysdeps/linux/mips/bits/sigaction.h

@@ -23,37 +23,22 @@
 #endif
 #endif
 
 
 /* Structure describing the action to be taken when a signal arrives.  */
 /* Structure describing the action to be taken when a signal arrives.  */
-struct sigaction
+struct sigaction {
-  {
+	unsigned        sa_flags;
-    /* Special flags.  */
-    unsigned int sa_flags;
-
-    /* Signal handler.  */
 #ifdef __USE_POSIX199309
 #ifdef __USE_POSIX199309
-    union
+	union {
-      {
+		__sighandler_t sa_handler;
-	/* Used if SA_SIGINFO is not set.  */
+		void (*sa_sigaction)(int, siginfo_t *, void *);
-	__sighandler_t sa_handler;
+	} __sigaction_handler;
-	/* Used if SA_SIGINFO is set.  */
+# define sa_handler     __sigaction_handler.sa_handler
-	void (*sa_sigaction) (int, siginfo_t *, void *);
+# define sa_sigaction   __sigaction_handler.sa_sigaction
-      }
-    __sigaction_handler;
-# define sa_handler    __sigaction_handler.sa_handler
-# define sa_sigaction  __sigaction_handler.sa_sigaction
 #else
 #else
-    __sighandler_t sa_handler;
+	__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];
 #endif
 #endif
-  };
+	sigset_t        sa_mask;
+	void            (*sa_restorer)(void);
+	/*int           s_resv[1]; - reserved [deleted in uclibc] */
+};
 
 
 /* Bits in `sa_flags'.  */
 /* Bits in `sa_flags'.  */
 /* Please note that some Linux kernels versions use different values for these
 /* 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;
 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
+# if _MIPS_SIM != _ABIO32
-static void restore_rt (void) __asm__ ("__restore_rt");
+#  ifdef __NR_rt_sigreturn
+static void restore_rt(void) __asm__ ("__restore_rt");
+#  endif
+#  ifdef __NR_sigreturn
+static void restore(void) __asm__ ("__restore");
+#  endif
 # 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
-#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 ACT is not NULL, change the action for SIG to *ACT.
    If OACT is not NULL, put the old action for SIG in *OACT.  */
    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;
 	int result;
-	struct kernel_sigaction kact, koact;
+	struct old_kernel_sigaction kact, koact;
-	enum {
-		SIGSET_MIN_SIZE = sizeof(kact.sa_mask) < sizeof(act->sa_mask)
-				? sizeof(kact.sa_mask) : sizeof(act->sa_mask)
-	};
 
 
 	if (act) {
 	if (act) {
 		kact.k_sa_handler = act->sa_handler;
 		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;
 		kact.sa_flags = act->sa_flags;
-# ifdef HAVE_SA_RESTORER
+# if _MIPS_SIM == _ABIO32
-#  if _MIPS_SIM == _ABIO32
 		kact.sa_restorer = act->sa_restorer;
 		kact.sa_restorer = act->sa_restorer;
-#  else
+# else
 		kact.sa_restorer = &restore_rt;
 		kact.sa_restorer = &restore_rt;
-#  endif
 # endif
 # endif
 	}
 	}
-
+	result = __syscall_sigaction(sig,
-	/* 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,
 			act ? &kact : NULL,
-			oact ? &koact : NULL,
+			oact ? &koact : NULL);
-			sizeof(kact.sa_mask));
+	if (result < 0) {
-
+		__set_errno(-result);
-	if (oact && result >= 0) {
+		return -1;
+	}
+	if (oact) {
 		oact->sa_handler = koact.k_sa_handler;
 		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;
 		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;
 }
 }
 
 
-
-#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
 #endif
 
 
+
 #ifndef LIBC_SIGACTION
 #ifndef LIBC_SIGACTION
-/* libc_hidden_proto(sigaction) */
 weak_alias(__libc_sigaction,sigaction)
 weak_alias(__libc_sigaction,sigaction)
 libc_hidden_weak(sigaction)
 libc_hidden_weak(sigaction)
 #endif
 #endif
 
 
+
 /* NOTE: Please think twice before making any changes to the bits of
 /* NOTE: Please think twice before making any changes to the bits of
    code below.  GDB needs some intimate knowledge about it to
    code below.  GDB needs some intimate knowledge about it to
    recognize them as signal trampolines, and make backtraces through
    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
    If you ever feel the need to make any changes, please notify the
    appropriate GDB maintainer.  */
    appropriate GDB maintainer.  */
 
 
-#define RESTORE(name, syscall) RESTORE2 (name, syscall)
+#define RESTORE(name, syscall) RESTORE2(name, syscall)
 #define RESTORE2(name, syscall) \
 #define RESTORE2(name, syscall) \
-__asm__ (					\
+__asm__ (						\
-   ".align 4\n"					\
+	".align 4\n"					\
-   "__" #name ":\n"				\
+	"__" #name ":\n"				\
-   "	li $2, " #syscall "\n"			\
+	"	li	$2, " #syscall "\n"		\
-   "	syscall\n"				\
+	"	syscall\n"				\
-   );
+);
 
 
 /* The return code for realtime-signals.  */
 /* The return code for realtime-signals.  */
 #if _MIPS_SIM != _ABIO32
 #if _MIPS_SIM != _ABIO32
 # ifdef __NR_rt_sigreturn
 # ifdef __NR_rt_sigreturn
-RESTORE (restore_rt, __NR_rt_sigreturn)
+RESTORE(restore_rt, __NR_rt_sigreturn)
 # endif
 # endif
 # ifdef __NR_sigreturn
 # ifdef __NR_sigreturn
-RESTORE (restore, __NR_sigreturn)
+RESTORE(restore, __NR_sigreturn)
 # endif
 # endif
 #endif
 #endif

+ 12 - 24
libc/sysdeps/linux/sparc/bits/sigaction.h

@@ -22,33 +22,21 @@
 #endif
 #endif
 
 
 /* Structure describing the action to be taken when a signal arrives.  */
 /* Structure describing the action to be taken when a signal arrives.  */
-struct sigaction
+struct sigaction {
-  {
-    /* Signal handler. */
 #ifdef __USE_POSIX199309
 #ifdef __USE_POSIX199309
-    union
+	union {
-      {
+		__sighandler_t sa_handler;
-	/* Used if SA_SIGINFO is not set.  */
+		void (*sa_sigaction)(int, siginfo_t *, void *);
-	__sighandler_t sa_handler;
+	} __sigaction_handler;
-	/* Used if SA_SIGINFO is set.  */
+# define sa_handler     __sigaction_handler.sa_handler
-	void (*sa_sigaction) (int, siginfo_t *, void *);
+# define sa_sigaction   __sigaction_handler.sa_sigaction
-      }
-    __sigaction_handler;
-# define sa_handler	__sigaction_handler.sa_handler
-# define sa_sigaction	__sigaction_handler.sa_sigaction
 #else
 #else
-    __sighandler_t sa_handler;
+	__sighandler_t  sa_handler;
 #endif
 #endif
-
+	unsigned long   sa_flags;
-    /* Additional set of signals to be blocked.  */
+	void            (*sa_restorer)(void);
-    __sigset_t sa_mask;
+	sigset_t        sa_mask;
-
+};
-    /* Special flags.  */
-    unsigned long sa_flags;
-
-    /* Not used by Linux/Sparc yet.  */
-    void (*sa_restorer) (void);
-  };
 
 
 
 
 /* Bits in `sa_flags'.  */
 /* Bits in `sa_flags'.  */

+ 35 - 54
libc/sysdeps/linux/x86_64/sigaction.c

@@ -25,9 +25,6 @@
 
 
 #include <sys/syscall.h>
 #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>
 #include <bits/kernel_sigaction.h>
 
 
 /* We do not globally define the SA_RESTORER flag so do it here.  */
 /* We do not globally define the SA_RESTORER flag so do it here.  */
@@ -35,64 +32,47 @@
 
 
 extern __typeof(sigaction) __libc_sigaction;
 extern __typeof(sigaction) __libc_sigaction;
 
 
+
 #ifdef __NR_rt_sigaction
 #ifdef __NR_rt_sigaction
+
 /* Using the hidden attribute here does not change the code but it
 /* Using the hidden attribute here does not change the code but it
    helps to avoid warnings.  */
    helps to avoid warnings.  */
-extern void restore_rt (void) __asm__ ("__restore_rt") attribute_hidden;
+extern void restore_rt(void) __asm__ ("__restore_rt") attribute_hidden;
-extern void restore (void) __asm__ ("__restore") attribute_hidden;
+extern void restore(void) __asm__ ("__restore") attribute_hidden;
-
-/* Experimentally off - libc_hidden_proto(memcpy) */
 
 
 /* If ACT is not NULL, change the action for SIG to *ACT.
 /* 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.  */
    If OACT is not NULL, put the old action for SIG in *OACT.  */
 int
 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 sigaction kact;
-	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)
-	};
 
 
 	if (act) {
 	if (act) {
-		kact.k_sa_handler = act->sa_handler;
+		memcpy(&kact, act, sizeof(kact));
-		memcpy (&kact.sa_mask, &act->sa_mask, SIGSET_MIN_SIZE);
+		kact.sa_flags |= SA_RESTORER;
-		kact.sa_flags = act->sa_flags | SA_RESTORER;
-
 		kact.sa_restorer = &restore_rt;
 		kact.sa_restorer = &restore_rt;
+		act = &kact;
 	}
 	}
-
 	/* NB: kernel (as of 2.6.25) will return EINVAL
 	/* NB: kernel (as of 2.6.25) will return EINVAL
-	 * if sizeof(kact.sa_mask) does not match kernel's sizeof(sigset_t) */
+	 * if sizeof(act->sa_mask) does not match kernel's sizeof(sigset_t) */
-	result = INLINE_SYSCALL (rt_sigaction, 4, sig,
+	return INLINE_SYSCALL(rt_sigaction, 4, sig, act, oact, sizeof(act->sa_mask));
-	                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;
 }
 }
+
 #else
 #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 ACT is not NULL, change the action for SIG to *ACT.
    If OACT is not NULL, put the old action for SIG in *OACT.  */
    If OACT is not NULL, put the old action for SIG in *OACT.  */
 int
 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;
 	int result;
 	struct old_kernel_sigaction kact, koact;
 	struct old_kernel_sigaction kact, koact;
 
 
 #ifdef SIGCANCEL
 #ifdef SIGCANCEL
 	if (sig == SIGCANCEL) {
 	if (sig == SIGCANCEL) {
-		__set_errno (EINVAL);
+		__set_errno(EINVAL);
 		return -1;
 		return -1;
 	}
 	}
 #endif
 #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_flags = act->sa_flags | SA_RESTORER;
 		kact.sa_restorer = &restore;
 		kact.sa_restorer = &restore;
 	}
 	}
-
+	__asm__ __volatile__ (
-	__asm__ __volatile__ ("syscall\n"
+		"syscall\n"
-	              : "=a" (result)
+		: "=a" (result)
-	              : "0" (__NR_sigaction), "mr" (sig),
+		: "0" (__NR_sigaction), "mr" (sig),
-	                "c" (act ? &kact : 0),
+		  "c" (act ? &kact : NULL),
-	                "d" (oact ? &koact : 0));
+		  "d" (oact ? &koact : NULL));
-
 	if (result < 0) {
 	if (result < 0) {
 		__set_errno(-result);
 		__set_errno(-result);
 		return -1;
 		return -1;
 	}
 	}
-
 	if (oact) {
 	if (oact) {
 		oact->sa_handler = koact.k_sa_handler;
 		oact->sa_handler = koact.k_sa_handler;
 		oact->sa_mask.__val[0] = koact.sa_mask;
 		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;
 	return result;
 }
 }
+
 #endif
 #endif
 
 
+
 #ifndef LIBC_SIGACTION
 #ifndef LIBC_SIGACTION
-/* libc_hidden_proto(sigaction) */
 weak_alias(__libc_sigaction,sigaction)
 weak_alias(__libc_sigaction,sigaction)
 libc_hidden_weak(sigaction)
 libc_hidden_weak(sigaction)
 #endif
 #endif
 
 
+
 /* NOTE: Please think twice before making any changes to the bits of
 /* NOTE: Please think twice before making any changes to the bits of
    code below.  GDB needs some intimate knowledge about it to
    code below.  GDB needs some intimate knowledge about it to
    recognize them as signal trampolines, and make backtraces through
    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
    If you ever feel the need to make any changes, please notify the
    appropriate GDB maintainer.  */
    appropriate GDB maintainer.  */
 
 
-#define RESTORE(name, syscall) RESTORE2 (name, syscall)
+#define RESTORE(name, syscall) RESTORE2(name, syscall)
-# define RESTORE2(name, syscall) \
+#define RESTORE2(name, syscall) \
-__asm__ (					\
+__asm__ (						\
-   ".text\n"					\
+	".text\n"					\
-   "__" #name ":\n"				\
+	"__" #name ":\n"				\
-   "	movq $" #syscall ", %rax\n"		\
+	"	movq	$" #syscall ", %rax\n"		\
-   "	syscall\n"				\
+	"	syscall\n"				\
-   );
+);
+
 #ifdef __NR_rt_sigaction
 #ifdef __NR_rt_sigaction
 /* The return code for realtime-signals.  */
 /* The return code for realtime-signals.  */
-RESTORE (restore_rt, __NR_rt_sigreturn)
+RESTORE(restore_rt, __NR_rt_sigreturn)
 #endif
 #endif
 #ifdef __NR_sigreturn
 #ifdef __NR_sigreturn
-RESTORE (restore, __NR_sigreturn)
+RESTORE(restore, __NR_sigreturn)
 #endif
 #endif

+ 10 - 37
libc/sysdeps/linux/xtensa/sigaction.c

@@ -15,52 +15,25 @@
 
 
 #define SA_RESTORER	0x04000000
 #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 sig, const struct sigaction *act,
-
-int __libc_sigaction (int signum, const struct sigaction *act,
 					  struct sigaction *oact)
 					  struct sigaction *oact)
 {
 {
-	struct kernel_sigaction kact, koact;
+	struct sigaction kact;
-	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;
 
 
-		if (kact.sa_flags & SA_RESTORER) {
+	if (act && !(act->sa_flags & SA_RESTORER)) {
-			kact.sa_restorer = act->sa_restorer;
+		memcpy(&kact, act, sizeof(kact));
-		} else {
+		kact.sa_restorer = __default_sa_restorer;
-			kact.sa_restorer = __default_sa_restorer;
+		kact.sa_flags |= SA_RESTORER;
-			kact.sa_flags |= SA_RESTORER;
+		act = &kact;
-		}
 	}
 	}
-
 	/* NB: kernel (as of 2.6.25) will return EINVAL
 	/* NB: kernel (as of 2.6.25) will return EINVAL
-	 * if sizeof(kact.sa_mask) does not match kernel's sizeof(sigset_t) */
+	 * if sizeof(act->sa_mask) does not match kernel's sizeof(sigset_t) */
-	result = __syscall_rt_sigaction(signum,
+	return __syscall_rt_sigaction(sig, act, oact, sizeof(act->sa_mask));
-			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;
 }
 }
 
 
 #ifndef LIBC_SIGACTION
 #ifndef LIBC_SIGACTION
-libc_hidden_proto(sigaction)
 weak_alias(__libc_sigaction, sigaction)
 weak_alias(__libc_sigaction, sigaction)
 libc_hidden_weak(sigaction)
 libc_hidden_weak(sigaction)
 #endif
 #endif

+ 2 - 0
libpthread/linuxthreads/sysdeps/pthread/sigaction.c

@@ -17,6 +17,8 @@
    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
    02111-1307 USA.  */
    02111-1307 USA.  */
 
 
+/* Somebody please explain what's going on here.  --vda */
+
 /* This is tricky.  GCC doesn't like #include_next in the primary
 /* 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
    source file and even if it did, the first #include_next is this
    exact file anyway.  */
    exact file anyway.  */