diff options
21 files changed, 355 insertions, 656 deletions
diff --git a/docs/sigaction.txt b/docs/sigaction.txt index b380e725b..667eeba41 100644 --- a/docs/sigaction.txt +++ b/docs/sigaction.txt @@ -242,4 +242,8 @@ To this effect:  * Document discovered arch quirks while debugging this mess. -* Deal with old_kernel_sigaction later. +* struct old_kernel_sigaction can't be disposed of in a similar way, +  we need to have userspace struct sigaction unchanged regardless +  whether we use "old" or "new" kernel sigaction() syscall. +  It's moot anyway because "old" one is long unused, it's from +  pre-2.2 kernels. diff --git a/include/signal.h b/include/signal.h index 2946f9c5f..c2b8b7476 100644 --- a/include/signal.h +++ b/include/signal.h @@ -56,13 +56,23 @@ typedef __sigset_t sigset_t;  #include <bits/types.h>  #include <bits/signum.h> +//TODO vda: pull out of bits/signum.h the following, +//which is the same for all arches: +//#define SIG_ERR    ((__sighandler_t) -1) /* Error return.  */ +//#define SIG_DFL    ((__sighandler_t) 0)  /* Default action.  */ +//#define SIG_IGN    ((__sighandler_t) 1)  /* Ignore signal.  */ +//#ifdef __USE_UNIX98 +//# define SIG_HOLD  ((__sighandler_t) 2)  /* Add signal to hold mask.  */ +//#endif +//#define SIGRTMIN   (__libc_current_sigrtmin()) +//#define SIGRTMAX   (__libc_current_sigrtmax()) +//#define __SIGRTMIN -- dont pull, it's arch specific +//#define __SIGRTMAX (_NSIG - 1)  #if defined __USE_XOPEN || defined __USE_XOPEN2K  # ifndef __pid_t_defined  typedef __pid_t pid_t;  #  define __pid_t_defined -#endif -#ifdef __USE_XOPEN  # endif  # ifndef __uid_t_defined  typedef __uid_t uid_t; @@ -79,10 +89,10 @@ typedef void (*__sighandler_t) (int);     requested.  */  extern __sighandler_t __sysv_signal (int __sig, __sighandler_t __handler)       __THROW; -#ifdef __USE_GNU +# ifdef __USE_GNU  extern __sighandler_t sysv_signal (int __sig, __sighandler_t __handler)       __THROW; -#endif +# endif  #endif /* __UCLIBC_HAS_OBSOLETE_SYSV_SIGNAL__ */  /* Set the handler for the signal SIG to HANDLER, returning the old @@ -118,14 +128,14 @@ extern __sighandler_t bsd_signal (int __sig, __sighandler_t __handler)  #ifdef __USE_POSIX  extern int kill (__pid_t __pid, int __sig) __THROW;  libc_hidden_proto(kill) -#endif /* Use POSIX.  */ +#endif  #if defined __USE_BSD || defined __USE_XOPEN_EXTENDED  /* Send SIG to all processes in process group PGRP.     If PGRP is zero, send SIG to all processes in     the current process's process group.  */  extern int killpg (__pid_t __pgrp, int __sig) __THROW; -#endif /* Use BSD || X/Open Unix.  */ +#endif  __BEGIN_NAMESPACE_STD  /* Raise signal SIG, i.e., send SIG to yourself.  */ @@ -195,8 +205,9 @@ extern int siggetmask (void) __THROW __attribute_deprecated__;  #endif /* Use BSD.  */ +/* Biggest signal number + 1 (including real-time signals).  */  #ifdef __USE_MISC -# define NSIG	_NSIG +# define NSIG  _NSIG  #endif  #ifdef __USE_GNU @@ -316,12 +327,12 @@ extern int sigqueue (__pid_t __pid, int __sig, __const union sigval __val)  #ifdef __USE_BSD -#ifdef __UCLIBC_HAS_SYS_SIGLIST__ +# ifdef __UCLIBC_HAS_SYS_SIGLIST__  /* Names of the signals.  This variable exists only for compatibility.     Use `strsignal' instead (see <string.h>).  */ -#define _sys_siglist sys_siglist +#  define _sys_siglist sys_siglist  extern __const char *__const sys_siglist[_NSIG]; -#endif /* __UCLIBC_HAS_SYS_SIGLIST__ */ +# endif  /* Structure passed to `sigvec'.  */  struct sigvec @@ -404,7 +415,7 @@ extern __sighandler_t sigset (int __sig, __sighandler_t __disp) __THROW;     be defined here.  */  # include <bits/pthreadtypes.h>  # include <bits/sigthread.h> -#endif /* use Unix98 */ +#endif  /* The following functions are used internally in the C library and in     other code which need deep insights.  */ diff --git a/libc/signal/sigaction.c b/libc/signal/sigaction.c index 25c1f8a74..23a2d78db 100644 --- a/libc/signal/sigaction.c +++ b/libc/signal/sigaction.c @@ -20,62 +20,30 @@  #include <errno.h>  #include <signal.h>  #include <string.h> -  #include <sys/syscall.h> -/* Experimentally off - libc_hidden_proto(memcpy) */ - -/* The difference here is that the sigaction structure used in the -   kernel is not the same as we use in the libc.  Therefore we must -   translate it here.  */  #include <bits/kernel_sigaction.h>  #ifndef LIBC_SIGACTION  extern __typeof(sigaction) __libc_sigaction;  #endif +  #if defined __NR_rt_sigaction  /* If ACT is not NULL, change the action for SIG to *ACT.     If OACT is not NULL, put the old action for SIG in *OACT.  */  int -__libc_sigaction (int sig, const struct sigaction *act, struct sigaction *oact) +__libc_sigaction(int sig, const struct sigaction *act, struct sigaction *oact)  { -	int result; -	struct kernel_sigaction kact, koact; -	enum { -		/* We try hard to actually have them equal, -		 * but just for paranoid reasons, be safe */ -		SIGSET_MIN_SIZE = sizeof(kact.sa_mask) < sizeof(act->sa_mask) -				? sizeof(kact.sa_mask) : sizeof(act->sa_mask) -	}; - -	if (act) { -		kact.k_sa_handler = act->sa_handler; -		memcpy (&kact.sa_mask, &act->sa_mask, SIGSET_MIN_SIZE); -		kact.sa_flags = act->sa_flags; -# ifdef HAVE_SA_RESTORER -		kact.sa_restorer = act->sa_restorer; -# endif -	} -  	/* NB: kernel (as of 2.6.25) will return EINVAL -	 * if sizeof(kact.sa_mask) does not match kernel's sizeof(sigset_t) */ -	result = __syscall_rt_sigaction(sig, -			act ? &kact : NULL, -			oact ? &koact : NULL, -			sizeof(kact.sa_mask)); - -	if (oact && result >= 0) { -		oact->sa_handler = koact.k_sa_handler; -		memcpy (&oact->sa_mask, &koact.sa_mask, SIGSET_MIN_SIZE); -		oact->sa_flags = koact.sa_flags; -# ifdef HAVE_SA_RESTORER -		oact->sa_restorer = koact.sa_restorer; -# endif -	} - -	return result; +	 * if sizeof(act->sa_mask) does not match kernel's sizeof(sigset_t). +	 * Try to catch this problem at uclibc build time:  */ +	struct BUG_sigset_size { +		int BUG_sigset_size +			[sizeof(act->sa_mask) != _NSIG / 8 ? 1 : -1]; +	}; +	return __syscall_rt_sigaction(sig, act, oact, sizeof(act->sa_mask));  }  #else @@ -83,7 +51,7 @@ __libc_sigaction (int sig, const struct sigaction *act, struct sigaction *oact)  /* If ACT is not NULL, change the action for SIG to *ACT.     If OACT is not NULL, put the old action for SIG in *OACT.  */  int -__libc_sigaction (int sig, const struct sigaction *act, struct sigaction *oact) +__libc_sigaction(int sig, const struct sigaction *act, struct sigaction *oact)  {  	int result;  	struct old_kernel_sigaction kact, koact; @@ -96,11 +64,9 @@ __libc_sigaction (int sig, const struct sigaction *act, struct sigaction *oact)  		kact.sa_restorer = act->sa_restorer;  # endif  	} -  	result = __syscall_sigaction(sig, -			       act ? &kact : NULL, -			       oact ? &koact : NULL); - +			act ? &kact : NULL, +			oact ? &koact : NULL);  	if (oact && result >= 0) {  		oact->sa_handler = koact.k_sa_handler;  		oact->sa_mask.__val[0] = koact.sa_mask; @@ -109,14 +75,13 @@ __libc_sigaction (int sig, const struct sigaction *act, struct sigaction *oact)  		oact->sa_restorer = koact.sa_restorer;  # endif  	} -  	return result;  }  #endif +  #ifndef LIBC_SIGACTION -/* libc_hidden_proto(sigaction) */  weak_alias(__libc_sigaction,sigaction)  libc_hidden_weak(sigaction)  #endif diff --git a/libc/sysdeps/linux/alpha/bits/kernel_sigaction.h b/libc/sysdeps/linux/alpha/bits/kernel_sigaction.h index 626af23fb..cd6b2133d 100644 --- a/libc/sysdeps/linux/alpha/bits/kernel_sigaction.h +++ b/libc/sysdeps/linux/alpha/bits/kernel_sigaction.h @@ -9,15 +9,12 @@ struct old_kernel_sigaction {  	unsigned int sa_flags;  }; -/* This is the sigaction structure from the Linux 2.1.68 kernel.  */ +/* In uclibc, userspace struct sigaction is identical to + * "new" struct kernel_sigaction (one from the Linux 2.1.68 kernel). + * See sigaction.h + */ -struct kernel_sigaction { -	__sighandler_t k_sa_handler; -	unsigned int sa_flags; -	sigset_t sa_mask; -}; - -extern int __syscall_rt_sigaction (int, const struct kernel_sigaction *, -	struct kernel_sigaction *, size_t) attribute_hidden; +extern int __syscall_rt_sigaction (int, const struct sigaction *, +	struct sigaction *, size_t) attribute_hidden;  #endif diff --git a/libc/sysdeps/linux/alpha/bits/sigaction.h b/libc/sysdeps/linux/alpha/bits/sigaction.h index 80feb2fa2..61dea1180 100644 --- a/libc/sysdeps/linux/alpha/bits/sigaction.h +++ b/libc/sysdeps/linux/alpha/bits/sigaction.h @@ -22,30 +22,21 @@  #endif  /* Structure describing the action to be taken when a signal arrives.  */ -struct sigaction -  { -    /* Signal handler.  */ +struct sigaction {  #ifdef __USE_POSIX199309 -    union -      { -	/* Used if SA_SIGINFO is not set.  */ -	__sighandler_t sa_handler; -	/* Used if SA_SIGINFO is set.  */ -	void (*sa_sigaction) (int, siginfo_t *, void *); -      } -    __sigaction_handler; -# define sa_handler	__sigaction_handler.sa_handler -# define sa_sigaction	__sigaction_handler.sa_sigaction +	union { +		__sighandler_t sa_handler; +		void (*sa_sigaction)(int, siginfo_t *, void *); +	} __sigaction_handler; +# define sa_handler     __sigaction_handler.sa_handler +# define sa_sigaction   __sigaction_handler.sa_sigaction  #else -    __sighandler_t sa_handler; +	__sighandler_t  sa_handler;  #endif - -    /* Additional set of signals to be blocked.  */ -    __sigset_t sa_mask; - -    /* Special flags.  */ -    unsigned int sa_flags; -  }; +	unsigned        sa_flags; +	sigset_t        sa_mask; +	/* Alpha has no sa_restorer field.  */ +};  /* Bits in `sa_flags'.  */  #define	SA_NOCLDSTOP  0x00000004 /* Don't send SIGCHLD when children stop.  */ diff --git a/libc/sysdeps/linux/arm/sigaction.c b/libc/sysdeps/linux/arm/sigaction.c index 2307d7add..01140aafb 100644 --- a/libc/sysdeps/linux/arm/sigaction.c +++ b/libc/sysdeps/linux/arm/sigaction.c @@ -34,100 +34,68 @@ extern __typeof(sigaction) __libc_sigaction;  /* When RT signals are in use we need to use a different return stub.  */  #ifdef __NR_rt_sigreturn  #define choose_restorer(flags)					\ -  (flags & SA_SIGINFO) ? __default_rt_sa_restorer		\ -  : __default_sa_restorer +	(flags & SA_SIGINFO) ? __default_rt_sa_restorer		\ +	: __default_sa_restorer  #else  #define choose_restorer(flags)					\ -  __default_sa_restorer +	__default_sa_restorer  #endif +  #ifdef __NR_rt_sigaction -/* Experimentally off - libc_hidden_proto(memcpy) */ +/* If ACT is not NULL, change the action for SIG to *ACT. +   If OACT is not NULL, put the old action for SIG in *OACT.  */ +int __libc_sigaction(int sig, const struct sigaction *act, struct sigaction *oact) +{ +	struct sigaction kact; +	if (act && !(act->sa_flags & SA_RESTORER)) { +		memcpy(&kact, act, sizeof(kact)); +		kact.sa_restorer = choose_restorer(kact.sa_flags); +		kact.sa_flags |= SA_RESTORER; +		act = &kact; +	} +	/* NB: kernel (as of 2.6.25) will return EINVAL +	 * if sizeof(act->sa_mask) does not match kernel's sizeof(sigset_t) */ +	return __syscall_rt_sigaction(sig, act, oact, sizeof(act->sa_mask)); +} + +#else  /* If ACT is not NULL, change the action for SIG to *ACT.     If OACT is not NULL, put the old action for SIG in *OACT.  */ -int __libc_sigaction (int sig, const struct sigaction *act, struct sigaction *oact) +int __libc_sigaction(int sig, const struct sigaction *act, struct sigaction *oact)  {  	int result; -	struct kernel_sigaction kact, koact; -	enum { -		SIGSET_MIN_SIZE = sizeof(kact.sa_mask) < sizeof(act->sa_mask) -				? sizeof(kact.sa_mask) : sizeof(act->sa_mask) -	}; +	struct old_kernel_sigaction kact, koact;  	if (act) {  		kact.k_sa_handler = act->sa_handler; -		memcpy (&kact.sa_mask, &act->sa_mask, SIGSET_MIN_SIZE); +		kact.sa_mask = act->sa_mask.__val[0];  		kact.sa_flags = act->sa_flags; -# ifdef HAVE_SA_RESTORER  		if (kact.sa_flags & SA_RESTORER) {  			kact.sa_restorer = act->sa_restorer;  		} else { -			kact.sa_restorer = choose_restorer (kact.sa_flags); +			kact.sa_restorer = choose_restorer(kact.sa_flags);  			kact.sa_flags |= SA_RESTORER;  		} -# endif  	} - -	/* NB: kernel (as of 2.6.25) will return EINVAL -	 * if sizeof(kact.sa_mask) does not match kernel's sizeof(sigset_t) */ -	result = __syscall_rt_sigaction(sig, +	result = __syscall_sigaction(sig,  			act ? &kact : NULL, -			oact ? &koact : NULL, -			sizeof(kact.sa_mask)); - +			oact ? &koact : NULL);  	if (oact && result >= 0) {  		oact->sa_handler = koact.k_sa_handler; -		memcpy (&oact->sa_mask, &koact.sa_mask, SIGSET_MIN_SIZE); +		oact->sa_mask.__val[0] = koact.sa_mask;  		oact->sa_flags = koact.sa_flags; -# ifdef HAVE_SA_RESTORER  		oact->sa_restorer = koact.sa_restorer; -# endif  	}  	return result;  } - -#else - -/* If ACT is not NULL, change the action for SIG to *ACT. -   If OACT is not NULL, put the old action for SIG in *OACT.  */ -int __libc_sigaction (int sig, const struct sigaction *act, struct sigaction *oact) -{ -    int result; -    struct old_kernel_sigaction kact, koact; - -    if (act) { -	kact.k_sa_handler = act->sa_handler; -	kact.sa_mask = act->sa_mask.__val[0]; -	kact.sa_flags = act->sa_flags; -# ifdef HAVE_SA_RESTORER -	if (kact.sa_flags & SA_RESTORER) { -	    kact.sa_restorer = act->sa_restorer; -	} else { -	    kact.sa_restorer = choose_restorer (kact.sa_flags); -	    kact.sa_flags |= SA_RESTORER; -	} -# endif -    } -    result = __syscall_sigaction(sig, act ? &kact : NULL, -	    oact ? &koact : NULL); -    if (oact && result >= 0) { -	oact->sa_handler = koact.k_sa_handler; -	oact->sa_mask.__val[0] = koact.sa_mask; -	oact->sa_flags = koact.sa_flags; -# ifdef HAVE_SA_RESTORER -	oact->sa_restorer = koact.sa_restorer; -# endif -    } -    return result; -} -  #endif +  #ifndef LIBC_SIGACTION -/* libc_hidden_proto(sigaction) */  weak_alias(__libc_sigaction,sigaction)  libc_hidden_weak(sigaction)  #endif diff --git a/libc/sysdeps/linux/avr32/sigaction.c b/libc/sysdeps/linux/avr32/sigaction.c index 8113c9ca6..61530912e 100644 --- a/libc/sysdeps/linux/avr32/sigaction.c +++ b/libc/sysdeps/linux/avr32/sigaction.c @@ -14,54 +14,30 @@  #define SA_RESTORER	0x04000000  extern void __default_rt_sa_restorer(void); -/* Experimentally off - libc_hidden_proto(memcpy) */ -  extern __typeof(sigaction) __libc_sigaction;  /*   * If act is not NULL, change the action for sig to *act.   * If oact is not NULL, put the old action for sig in *oact.   */ -int __libc_sigaction(int signum, const struct sigaction *act, -		     struct sigaction *oldact) +int __libc_sigaction(int sig, const struct sigaction *act, +		     struct sigaction *oact)  { -	struct kernel_sigaction kact, koact; -	int result; -	enum { -		SIGSET_MIN_SIZE = sizeof(kact.sa_mask) < sizeof(act->sa_mask) -				? sizeof(kact.sa_mask) : sizeof(act->sa_mask) -	}; +	struct sigaction kact; -	if (act) { -		kact.k_sa_handler = act->sa_handler; -		memcpy(&kact.sa_mask, &act->sa_mask, SIGSET_MIN_SIZE); -		kact.sa_flags = act->sa_flags; -		if (kact.sa_flags & SA_RESTORER) -			kact.sa_restorer = act->sa_restorer; -		else -			kact.sa_restorer = __default_rt_sa_restorer; +	if (act && !(act->sa_flags & SA_RESTORER)) { +		memcpy(&kact, act, sizeof(kact)); +		kact.sa_restorer = __default_rt_sa_restorer;  		kact.sa_flags |= SA_RESTORER; +		act = &kact;  	}  	/* NB: kernel (as of 2.6.25) will return EINVAL -	 * if sizeof(kact.sa_mask) does not match kernel's sizeof(sigset_t) */ -	result = __syscall_rt_sigaction(signum, -			act ? &kact : NULL, -			oldact ? &koact : NULL, -			sizeof(kact.sa_mask)); - -	if (oldact && result >= 0) { -		oldact->sa_handler = koact.k_sa_handler; -		memcpy(&oldact->sa_mask, &koact.sa_mask, SIGSET_MIN_SIZE); -		oldact->sa_flags = koact.sa_flags; -		oldact->sa_restorer = koact.sa_restorer; -	} - -	return result; +	 * if sizeof(act->sa_mask) does not match kernel's sizeof(sigset_t) */ +	return __syscall_rt_sigaction(sig, act, oact, sizeof(act->sa_mask));  }  #ifndef LIBC_SIGACTION -/* libc_hidden_proto(sigaction) */  weak_alias(__libc_sigaction, sigaction)  libc_hidden_weak(sigaction)  #endif diff --git a/libc/sysdeps/linux/common/bits/kernel_sigaction.h b/libc/sysdeps/linux/common/bits/kernel_sigaction.h index a39aa324b..f74e0a28a 100644 --- a/libc/sysdeps/linux/common/bits/kernel_sigaction.h +++ b/libc/sysdeps/linux/common/bits/kernel_sigaction.h @@ -4,72 +4,33 @@  /* This file provides whatever this particular arch's kernel thinks   * the sigaction struct should look like... */ -#undef NO_OLD_SIGACTION -#if defined(__mips__) -/* We have libc/sysdeps/linux/mips/bits/kernel_sigaction.h, - * so this should never be used. Lets see whether it is true. */ -struct BUG_is_here { char BUG_is_here[-1]; }; +#if defined(__ia64__)  #undef HAVE_SA_RESTORER -/* This is the sigaction structure from the Linux 2.1.24 kernel.  */ -#include <sgidefs.h> -struct old_kernel_sigaction { -    __sighandler_t  k_sa_handler; -    unsigned int    sa_flags; -    unsigned long   sa_mask; -}; -#define _KERNEL_NSIG           128 -#define _KERNEL_NSIG_BPW       32 -#define _KERNEL_NSIG_WORDS     (_KERNEL_NSIG / _KERNEL_NSIG_BPW) -typedef struct { -    unsigned long sig[_KERNEL_NSIG_WORDS]; -} kernel_sigset_t; -/* This is the sigaction structure from the Linux 2.1.68 kernel.  */ -struct kernel_sigaction { -    unsigned int    sa_flags; -    __sighandler_t  k_sa_handler; -    kernel_sigset_t sa_mask; -    void            (*sa_restorer)(void); -    int             s_resv[1]; /* reserved */ -}; - -#elif defined(__ia64__) - -#define NO_OLD_SIGACTION -#undef HAVE_SA_RESTORER -struct kernel_sigaction { -	__sighandler_t k_sa_handler; -	unsigned long sa_flags; -	sigset_t sa_mask; -};  #else  #define HAVE_SA_RESTORER  /* This is the sigaction structure from the Linux 2.1.20 kernel.  */  struct old_kernel_sigaction { -    __sighandler_t k_sa_handler; -    unsigned long sa_mask; -    unsigned long sa_flags; -    void (*sa_restorer) (void); -}; -/* This is the sigaction structure from the Linux 2.1.68 kernel.  */ -struct kernel_sigaction { -    __sighandler_t k_sa_handler; -    unsigned long sa_flags; -    void (*sa_restorer) (void); -    sigset_t sa_mask; +	__sighandler_t k_sa_handler; +	unsigned long sa_mask; +	unsigned long sa_flags; +	void (*sa_restorer)(void);  }; +/* In uclibc, userspace struct sigaction is identical to + * "new" struct kernel_sigaction (one from the Linux 2.1.68 kernel). + * See sigaction.h + */ -#endif - -#ifndef NO_OLD_SIGACTION -extern int __syscall_sigaction (int, const struct old_kernel_sigaction *, +extern int __syscall_sigaction(int, const struct old_kernel_sigaction *,  	struct old_kernel_sigaction *) attribute_hidden; +  #endif -extern int __syscall_rt_sigaction (int, const struct kernel_sigaction *, -	struct kernel_sigaction *, size_t) attribute_hidden; + +extern int __syscall_rt_sigaction(int, const struct sigaction *, +	struct sigaction *, size_t) attribute_hidden;  #endif /* _BITS_SIGACTION_STRUCT_H */ diff --git a/libc/sysdeps/linux/common/bits/sigaction.h b/libc/sysdeps/linux/common/bits/sigaction.h index 48cc5312f..7489aa878 100644 --- a/libc/sysdeps/linux/common/bits/sigaction.h +++ b/libc/sysdeps/linux/common/bits/sigaction.h @@ -21,34 +21,26 @@  # error "Never include <bits/sigaction.h> directly; use <signal.h> instead."  #endif -/* Structure describing the action to be taken when a signal arrives.  */ -struct sigaction -  { -    /* Signal handler.  */ +/* Structure describing the action to be taken when a signal arrives. + * In uclibc, it is identical to "new" struct kernel_sigaction + * (one from the Linux 2.1.68 kernel). + * This minimizes amount of translation in sigaction(). + */ +struct sigaction {  #ifdef __USE_POSIX199309 -    union -      { -	/* Used if SA_SIGINFO is not set.  */ -	__sighandler_t sa_handler; -	/* Used if SA_SIGINFO is set.  */ -	void (*sa_sigaction) (int, siginfo_t *, void *); -      } -    __sigaction_handler; -# define sa_handler	__sigaction_handler.sa_handler -# define sa_sigaction	__sigaction_handler.sa_sigaction +	union { +		__sighandler_t sa_handler; +		void (*sa_sigaction)(int, siginfo_t *, void *); +	} __sigaction_handler; +# define sa_handler     __sigaction_handler.sa_handler +# define sa_sigaction   __sigaction_handler.sa_sigaction  #else -    __sighandler_t sa_handler; +	__sighandler_t  sa_handler;  #endif - -    /* Additional set of signals to be blocked.  */ -    __sigset_t sa_mask; - -    /* Special flags.  */ -    int sa_flags; - -    /* Restore handler.  */ -    void (*sa_restorer) (void); -  }; +	unsigned long   sa_flags; +	void            (*sa_restorer)(void); +	sigset_t        sa_mask; +};  /* Bits in `sa_flags'.  */  #define	SA_NOCLDSTOP  1		 /* Don't send SIGCHLD when children stop.  */ diff --git a/libc/sysdeps/linux/common/bits/sigset.h b/libc/sysdeps/linux/common/bits/sigset.h index 7ec87eb1d..2f67a4ebf 100644 --- a/libc/sysdeps/linux/common/bits/sigset.h +++ b/libc/sysdeps/linux/common/bits/sigset.h @@ -29,10 +29,8 @@ typedef int __sig_atomic_t;   * where they might have (or had in the past) 32 signals only,   * I hope it's irrelevant now.   * Signal 0 does not exist, so we have signals 1..64, not 0..63. - * Note that struct sigaction has embedded sigset_t, - * and this necessitates translation in sigaction() - * to convert it to struct kernel_sigaction. - * See libc/.../sigaction.c, libc/.../kernel_sigaction.h + * In uclibc, kernel and userspace sigset_t is always the same. + * BTW, struct sigaction is also the same on kernel and userspace side.   */  #if defined(__mips__)  # define _SIGSET_NWORDS	(128 / (8 * sizeof (unsigned long))) diff --git a/libc/sysdeps/linux/hppa/bits/kernel_sigaction.h b/libc/sysdeps/linux/hppa/bits/kernel_sigaction.h index 8a8491da0..1c093a522 100644 --- a/libc/sysdeps/linux/hppa/bits/kernel_sigaction.h +++ b/libc/sysdeps/linux/hppa/bits/kernel_sigaction.h @@ -12,15 +12,12 @@ struct old_kernel_sigaction {  	unsigned long sa_flags;  }; -/* This is the sigaction structure from the Linux 2.1.68 kernel.  */ +/* In uclibc, userspace struct sigaction is identical to + * "new" struct kernel_sigaction (one from the Linux 2.1.68 kernel). + * See sigaction.h + */ -struct kernel_sigaction { -	__sighandler_t k_sa_handler; -	unsigned long sa_flags; -	sigset_t sa_mask; -}; - -extern int __syscall_rt_sigaction (int, const struct kernel_sigaction *, -	struct kernel_sigaction *, size_t) attribute_hidden; +extern int __syscall_rt_sigaction (int, const struct sigaction *, +	struct sigaction *, size_t) attribute_hidden;  #endif diff --git a/libc/sysdeps/linux/hppa/bits/sigaction.h b/libc/sysdeps/linux/hppa/bits/sigaction.h index 33f2b237b..3dac69e73 100644 --- a/libc/sysdeps/linux/hppa/bits/sigaction.h +++ b/libc/sysdeps/linux/hppa/bits/sigaction.h @@ -22,30 +22,21 @@  #endif  /* Structure describing the action to be taken when a signal arrives.  */ -struct sigaction -  { -    /* Signal handler.  */ +struct sigaction {  #ifdef __USE_POSIX199309 -    union -      { -	/* Used if SA_SIGINFO is not set.  */ -	__sighandler_t sa_handler; -	/* Used if SA_SIGINFO is set.  */ -	void (*sa_sigaction) (int, siginfo_t *, void *); -      } -    __sigaction_handler; -# define sa_handler	__sigaction_handler.sa_handler -# define sa_sigaction	__sigaction_handler.sa_sigaction +	union { +		__sighandler_t sa_handler; +		void (*sa_sigaction)(int, siginfo_t *, void *); +	} __sigaction_handler; +# define sa_handler     __sigaction_handler.sa_handler +# define sa_sigaction   __sigaction_handler.sa_sigaction  #else -    __sighandler_t sa_handler; +	__sighandler_t  sa_handler;  #endif - -    /* Special flags.  */ -    unsigned long int sa_flags; - -    /* Additional set of signals to be blocked.  */ -    __sigset_t sa_mask; -  }; +	unsigned long   sa_flags; +	sigset_t        sa_mask; +	/* HPPA has no sa_restorer field.  */ +};  /* Bits in `sa_flags'.  */ diff --git a/libc/sysdeps/linux/i386/sigaction.c b/libc/sysdeps/linux/i386/sigaction.c index a69c872a7..602f759a4 100644 --- a/libc/sysdeps/linux/i386/sigaction.c +++ b/libc/sysdeps/linux/i386/sigaction.c @@ -29,115 +29,89 @@  extern __typeof(sigaction) __libc_sigaction; +  #if defined __NR_rt_sigaction -/* Experimentally off - libc_hidden_proto(memcpy) */ -extern void restore_rt (void) __asm__ ("__restore_rt") attribute_hidden; -extern void restore (void) __asm__ ("__restore") attribute_hidden; +extern void restore_rt(void) __asm__ ("__restore_rt") attribute_hidden; +extern void restore(void) __asm__ ("__restore") attribute_hidden;  /* If ACT is not NULL, change the action for SIG to *ACT.     If OACT is not NULL, put the old action for SIG in *OACT.  */ -int __libc_sigaction (int sig, const struct sigaction *act, struct sigaction *oact) +int __libc_sigaction(int sig, const struct sigaction *act, struct sigaction *oact)  { -	int result; -	struct kernel_sigaction kact, koact; -	enum { -		SIGSET_MIN_SIZE = sizeof(kact.sa_mask) < sizeof(act->sa_mask) -				? sizeof(kact.sa_mask) : sizeof(act->sa_mask) -	}; +	struct sigaction kact;  #ifdef SIGCANCEL  	if (sig == SIGCANCEL) { -		__set_errno (EINVAL); +		__set_errno(EINVAL);  		return -1;  	}  #endif -  	if (act) { -		kact.k_sa_handler = act->sa_handler; -		memcpy (&kact.sa_mask, &act->sa_mask, SIGSET_MIN_SIZE); -		kact.sa_flags = act->sa_flags; - -		kact.sa_flags = act->sa_flags | SA_RESTORER; -		kact.sa_restorer = ((act->sa_flags & SA_SIGINFO) -			? &restore_rt : &restore); +		memcpy(&kact, act, sizeof(kact)); +		kact.sa_flags |= SA_RESTORER; +		kact.sa_restorer = (act->sa_flags & SA_SIGINFO) ? &restore_rt : &restore; +		act = &kact;  	} -  	/* NB: kernel (as of 2.6.25) will return EINVAL -	 * if sizeof(kact.sa_mask) does not match kernel's sizeof(sigset_t) */ -	result = __syscall_rt_sigaction(sig, -			act ? &kact : NULL, -			oact ? &koact : NULL, -			sizeof(kact.sa_mask)); - -	if (oact && result >= 0) { -		oact->sa_handler = koact.k_sa_handler; -		memcpy (&oact->sa_mask, &koact.sa_mask, SIGSET_MIN_SIZE); -		oact->sa_flags = koact.sa_flags; -		oact->sa_restorer = koact.sa_restorer; -	} -	return result; +	 * if sizeof(act->sa_mask) does not match kernel's sizeof(sigset_t) */ +	return __syscall_rt_sigaction(sig, act, oact, sizeof(act->sa_mask));  } -  #else -extern void restore (void) __asm__ ("__restore") attribute_hidden; + +extern void restore(void) __asm__ ("__restore") attribute_hidden;  /* If ACT is not NULL, change the action for SIG to *ACT.     If OACT is not NULL, put the old action for SIG in *OACT.  */ -int __libc_sigaction (int sig, const struct sigaction *act, struct sigaction *oact) +int __libc_sigaction(int sig, const struct sigaction *act, struct sigaction *oact)  { -    int result; -    struct old_kernel_sigaction kact, koact; +	int result; +	struct old_kernel_sigaction kact, koact;  #ifdef SIGCANCEL -    if (sig == SIGCANCEL) { -	__set_errno (EINVAL); -	return -1; -    } +	if (sig == SIGCANCEL) { +		__set_errno(EINVAL); +		return -1; +	}  #endif - -    if (act) { -	kact.k_sa_handler = act->sa_handler; -	kact.sa_mask = act->sa_mask.__val[0]; -	kact.sa_flags = act->sa_flags | SA_RESTORER; -	kact.sa_restorer = &restore; -    } - -    __asm__ __volatile__ ("pushl %%ebx\n" -	    "movl %3, %%ebx\n" -	    "int $0x80\n" -	    "popl %%ebx" -	    : "=a" (result), "=m" (koact) -	    : "0" (__NR_sigaction), "r" (sig), "m" (kact), -	    "c" (act ? &kact : 0), -	    "d" (oact ? &koact : 0)); - -    if (result < 0) { -	__set_errno(-result); -	return -1; -    } - -    if (oact) { -	oact->sa_handler = koact.k_sa_handler; -	oact->sa_mask.__val[0] = koact.sa_mask; -	oact->sa_flags = koact.sa_flags; -	oact->sa_restorer = koact.sa_restorer; -    } -    return result; +	if (act) { +		kact.k_sa_handler = act->sa_handler; +		kact.sa_mask = act->sa_mask.__val[0]; +		kact.sa_flags = act->sa_flags | SA_RESTORER; +		kact.sa_restorer = &restore; +	} +	__asm__ __volatile__ ( +		"	pushl	%%ebx\n" +		"	movl	%3, %%ebx\n" +		"	int	$0x80\n" +		"	popl	%%ebx\n" +		: "=a" (result), "=m" (koact) +		: "0" (__NR_sigaction), "r" (sig), "m" (kact), +		  "c" (act ? &kact : NULL), +		  "d" (oact ? &koact : NULL)); +	if (result < 0) { +		__set_errno(-result); +		return -1; +	} +	if (oact) { +		oact->sa_handler = koact.k_sa_handler; +		oact->sa_mask.__val[0] = koact.sa_mask; +		oact->sa_flags = koact.sa_flags; +		oact->sa_restorer = koact.sa_restorer; +	} +	return result;  }  #endif +  #ifndef LIBC_SIGACTION -/* libc_hidden_proto(sigaction) */  weak_alias(__libc_sigaction,sigaction)  libc_hidden_weak(sigaction)  #endif - -  /* NOTE: Please think twice before making any changes to the bits of     code below.  GDB needs some intimate knowledge about it to     recognize them as signal trampolines, and make backtraces through @@ -146,33 +120,31 @@ libc_hidden_weak(sigaction)     If you ever feel the need to make any changes, please notify the     appropriate GDB maintainer.  */ -#define RESTORE(name, syscall) RESTORE2 (name, syscall) +#define RESTORE(name, syscall) RESTORE2(name, syscall)  #define RESTORE2(name, syscall) \ -__asm__						\ -  (						\ -   ".text\n"					\ -   "__" #name ":\n"				\ -   "	movl $" #syscall ", %eax\n"		\ -   "	int  $0x80"				\ -   ); +__asm__	(						\ +	".text\n"					\ +	"__" #name ":\n"				\ +	"	movl	$" #syscall ", %eax\n"		\ +	"	int	$0x80\n"			\ +);  #ifdef __NR_rt_sigaction  /* The return code for realtime-signals.  */ -RESTORE (restore_rt, __NR_rt_sigreturn) +RESTORE(restore_rt, __NR_rt_sigreturn)  #endif  #ifdef __NR_sigreturn  /* For the boring old signals.  */  # undef RESTORE2  # define RESTORE2(name, syscall) \ -__asm__						\ -  (						\ -   ".text\n"					\ -   "__" #name ":\n"				\ -   "	popl %eax\n"				\ -   "	movl $" #syscall ", %eax\n"		\ -   "	int  $0x80"				\ -   ); - -RESTORE (restore, __NR_sigreturn) +__asm__ (						\ +	".text\n"					\ +	"__" #name ":\n"				\ +	"	popl	%eax\n"				\ +	"	movl	$" #syscall ", %eax\n"		\ +	"	int	$0x80\n"			\ +); + +RESTORE(restore, __NR_sigreturn)  #endif diff --git a/libc/sysdeps/linux/ia64/bits/sigaction.h b/libc/sysdeps/linux/ia64/bits/sigaction.h index 11599d520..4049402c1 100644 --- a/libc/sysdeps/linux/ia64/bits/sigaction.h +++ b/libc/sysdeps/linux/ia64/bits/sigaction.h @@ -22,30 +22,21 @@  #endif  /* Structure describing the action to be taken when a signal arrives.  */ -struct sigaction -  { -    /* Signal handler.  */ +struct sigaction {  #ifdef __USE_POSIX199309 -    union -      { -	/* Used if SA_SIGINFO is not set.  */ -	__sighandler_t sa_handler; -	/* Used if SA_SIGINFO is set.  */ -	void (*sa_sigaction) (int, siginfo_t *, void *); -      } -    __sigaction_handler; -# define sa_handler	__sigaction_handler.sa_handler -# define sa_sigaction	__sigaction_handler.sa_sigaction +	union { +		__sighandler_t sa_handler; +		void (*sa_sigaction)(int, siginfo_t *, void *); +	} __sigaction_handler; +# define sa_handler     __sigaction_handler.sa_handler +# define sa_sigaction   __sigaction_handler.sa_sigaction  #else -    __sighandler_t sa_handler; +	__sighandler_t  sa_handler;  #endif - -    /* Special flags.  */ -    unsigned long int sa_flags; - -    /* Additional set of signals to be blocked.  */ -    __sigset_t sa_mask; -  }; +	unsigned long   sa_flags; +	sigset_t        sa_mask; +	/* IA64 has no sa_restorer field.  */ +};  /* Bits in `sa_flags'.  */  #define SA_NOCLDSTOP  0x00000001 /* Don't send SIGCHLD when children stop.  */ diff --git a/libc/sysdeps/linux/mips/bits/kernel_sigaction.h b/libc/sysdeps/linux/mips/bits/kernel_sigaction.h index 6a7b939c4..2048095c8 100644 --- a/libc/sysdeps/linux/mips/bits/kernel_sigaction.h +++ b/libc/sysdeps/linux/mips/bits/kernel_sigaction.h @@ -24,25 +24,12 @@ struct old_kernel_sigaction {  #endif  }; +/* In uclibc, userspace struct sigaction is identical to + * "new" struct kernel_sigaction (one from the Linux 2.1.68 kernel). + * See sigaction.h + */ -#define _KERNEL_NSIG	       128 -#define _KERNEL_NSIG_BPW       _MIPS_SZLONG -#define _KERNEL_NSIG_WORDS     (_KERNEL_NSIG / _KERNEL_NSIG_BPW) - -typedef struct { -	unsigned long sig[_KERNEL_NSIG_WORDS]; -} kernel_sigset_t; - -/* This is the sigaction structure from the Linux 2.1.68 kernel.  */ -struct kernel_sigaction { -	unsigned int	sa_flags; -	__sighandler_t	k_sa_handler; -	kernel_sigset_t	sa_mask; -	void		(*sa_restorer)(void); -	int		s_resv[1]; /* reserved */ -}; - -extern int __syscall_rt_sigaction (int, const struct kernel_sigaction *, -	struct kernel_sigaction *, size_t) attribute_hidden; +extern int __syscall_rt_sigaction (int, const struct sigaction *, +	struct sigaction *, size_t) attribute_hidden;  #endif diff --git a/libc/sysdeps/linux/mips/bits/sigaction.h b/libc/sysdeps/linux/mips/bits/sigaction.h index d04e25f76..cc689d149 100644 --- a/libc/sysdeps/linux/mips/bits/sigaction.h +++ b/libc/sysdeps/linux/mips/bits/sigaction.h @@ -23,37 +23,22 @@  #endif  /* Structure describing the action to be taken when a signal arrives.  */ -struct sigaction -  { -    /* Special flags.  */ -    unsigned int sa_flags; - -    /* Signal handler.  */ +struct sigaction { +	unsigned        sa_flags;  #ifdef __USE_POSIX199309 -    union -      { -	/* Used if SA_SIGINFO is not set.  */ -	__sighandler_t sa_handler; -	/* Used if SA_SIGINFO is set.  */ -	void (*sa_sigaction) (int, siginfo_t *, void *); -      } -    __sigaction_handler; -# define sa_handler    __sigaction_handler.sa_handler -# define sa_sigaction  __sigaction_handler.sa_sigaction +	union { +		__sighandler_t sa_handler; +		void (*sa_sigaction)(int, siginfo_t *, void *); +	} __sigaction_handler; +# define sa_handler     __sigaction_handler.sa_handler +# define sa_sigaction   __sigaction_handler.sa_sigaction  #else -    __sighandler_t sa_handler; -#endif -    /* Additional set of signals to be blocked.  */ -    __sigset_t sa_mask; - -    /* The ABI says here are two unused ints following. */ -    /* Restore handler.  */ -    void (*sa_restorer) (void); - -#if _MIPS_SZPTR < 64 -    int sa_resv[1]; +	__sighandler_t  sa_handler;  #endif -  }; +	sigset_t        sa_mask; +	void            (*sa_restorer)(void); +	/*int           s_resv[1]; - reserved [deleted in uclibc] */ +};  /* Bits in `sa_flags'.  */  /* Please note that some Linux kernels versions use different values for these diff --git a/libc/sysdeps/linux/mips/sigaction.c b/libc/sysdeps/linux/mips/sigaction.c index 7c933ffd5..f2d2747b5 100644 --- a/libc/sysdeps/linux/mips/sigaction.c +++ b/libc/sysdeps/linux/mips/sigaction.c @@ -29,113 +29,82 @@  extern __typeof(sigaction) __libc_sigaction; -#ifdef __NR_rt_sigaction - -/* Experimentally off - libc_hidden_proto(memcpy) */ -#if _MIPS_SIM != _ABIO32 +#ifdef __NR_rt_sigaction -# ifdef __NR_rt_sigreturn -static void restore_rt (void) __asm__ ("__restore_rt"); +# if _MIPS_SIM != _ABIO32 +#  ifdef __NR_rt_sigreturn +static void restore_rt(void) __asm__ ("__restore_rt"); +#  endif +#  ifdef __NR_sigreturn +static void restore(void) __asm__ ("__restore"); +#  endif  # endif -# ifdef __NR_sigreturn -static void restore (void) __asm__ ("__restore"); + +/* If ACT is not NULL, change the action for SIG to *ACT. +   If OACT is not NULL, put the old action for SIG in *OACT.  */ +int __libc_sigaction(int sig, const struct sigaction *act, struct sigaction *oact) +{ +# if _MIPS_SIM != _ABIO32 +	struct sigaction kact; +	if (act) { +		memcpy(&kact, act, sizeof(kact)); +		kact.sa_restorer = &restore_rt; +		act = &kact; +	}  # endif -#endif + +	/* NB: kernel (as of 2.6.25) will return EINVAL +	 * if sizeof(act->sa_mask) does not match kernel's sizeof(sigset_t) */ +	return __syscall_rt_sigaction(sig, act, oact, sizeof(act->sa_mask)); +} + +#else + +extern void restore(void) __asm__ ("__restore") attribute_hidden;  /* If ACT is not NULL, change the action for SIG to *ACT.     If OACT is not NULL, put the old action for SIG in *OACT.  */ -int __libc_sigaction (int sig, const struct sigaction *act, struct sigaction *oact) +int __libc_sigaction(int sig, const struct sigaction *act, struct sigaction *oact)  {  	int result; -	struct kernel_sigaction kact, koact; -	enum { -		SIGSET_MIN_SIZE = sizeof(kact.sa_mask) < sizeof(act->sa_mask) -				? sizeof(kact.sa_mask) : sizeof(act->sa_mask) -	}; +	struct old_kernel_sigaction kact, koact;  	if (act) {  		kact.k_sa_handler = act->sa_handler; -		memcpy (&kact.sa_mask, &act->sa_mask, SIGSET_MIN_SIZE); +		kact.sa_mask = act->sa_mask.__val[0];  		kact.sa_flags = act->sa_flags; -# ifdef HAVE_SA_RESTORER -#  if _MIPS_SIM == _ABIO32 +# if _MIPS_SIM == _ABIO32  		kact.sa_restorer = act->sa_restorer; -#  else +# else  		kact.sa_restorer = &restore_rt; -#  endif  # endif  	} - -	/* NB: kernel (as of 2.6.25) will return EINVAL -	 * if sizeof(kact.sa_mask) does not match kernel's sizeof(sigset_t) */ -	result = __syscall_rt_sigaction(sig, +	result = __syscall_sigaction(sig,  			act ? &kact : NULL, -			oact ? &koact : NULL, -			sizeof(kact.sa_mask)); - -	if (oact && result >= 0) { +			oact ? &koact : NULL); +	if (result < 0) { +		__set_errno(-result); +		return -1; +	} +	if (oact) {  		oact->sa_handler = koact.k_sa_handler; -		memcpy (&oact->sa_mask, &koact.sa_mask, SIGSET_MIN_SIZE); +		oact->sa_mask.__val[0] = koact.sa_mask;  		oact->sa_flags = koact.sa_flags; -# ifdef HAVE_SA_RESTORER  		oact->sa_restorer = koact.sa_restorer; -# endif  	}  	return result;  } - -#else -extern void restore (void) __asm__ ("__restore") attribute_hidden; - -/* If ACT is not NULL, change the action for SIG to *ACT. -   If OACT is not NULL, put the old action for SIG in *OACT.  */ -int __libc_sigaction (int sig, const struct sigaction *act, struct sigaction *oact) -{ -    int result; -    struct old_kernel_sigaction kact, koact; - -    if (act) { -	kact.k_sa_handler = act->sa_handler; -	kact.sa_mask = act->sa_mask.__val[0]; -	kact.sa_flags = act->sa_flags; -# ifdef HAVE_SA_RESTORER -#  if _MIPS_SIM == _ABIO32 -	kact.sa_restorer = act->sa_restorer; -#  else -	kact.sa_restorer = &restore_rt; -#  endif -# endif -    } - -    result = __syscall_sigaction(sig, act ? &kact : NULL, -	    oact ? &koact : NULL); - -    if (result < 0) { -	__set_errno(-result); -	return -1; -    } - -    if (oact) { -	oact->sa_handler = koact.k_sa_handler; -	oact->sa_mask.__val[0] = koact.sa_mask; -	oact->sa_flags = koact.sa_flags; -# ifdef HAVE_SA_RESTORER -	oact->sa_restorer = koact.sa_restorer; -# endif -    } -    return result; -} -  #endif +  #ifndef LIBC_SIGACTION -/* libc_hidden_proto(sigaction) */  weak_alias(__libc_sigaction,sigaction)  libc_hidden_weak(sigaction)  #endif +  /* NOTE: Please think twice before making any changes to the bits of     code below.  GDB needs some intimate knowledge about it to     recognize them as signal trampolines, and make backtraces through @@ -144,21 +113,21 @@ libc_hidden_weak(sigaction)     If you ever feel the need to make any changes, please notify the     appropriate GDB maintainer.  */ -#define RESTORE(name, syscall) RESTORE2 (name, syscall) +#define RESTORE(name, syscall) RESTORE2(name, syscall)  #define RESTORE2(name, syscall) \ -__asm__ (					\ -   ".align 4\n"					\ -   "__" #name ":\n"				\ -   "	li $2, " #syscall "\n"			\ -   "	syscall\n"				\ -   ); +__asm__ (						\ +	".align 4\n"					\ +	"__" #name ":\n"				\ +	"	li	$2, " #syscall "\n"		\ +	"	syscall\n"				\ +);  /* The return code for realtime-signals.  */  #if _MIPS_SIM != _ABIO32  # ifdef __NR_rt_sigreturn -RESTORE (restore_rt, __NR_rt_sigreturn) +RESTORE(restore_rt, __NR_rt_sigreturn)  # endif  # ifdef __NR_sigreturn -RESTORE (restore, __NR_sigreturn) +RESTORE(restore, __NR_sigreturn)  # endif  #endif diff --git a/libc/sysdeps/linux/sparc/bits/sigaction.h b/libc/sysdeps/linux/sparc/bits/sigaction.h index ee4196764..be9bc028a 100644 --- a/libc/sysdeps/linux/sparc/bits/sigaction.h +++ b/libc/sysdeps/linux/sparc/bits/sigaction.h @@ -22,33 +22,21 @@  #endif  /* Structure describing the action to be taken when a signal arrives.  */ -struct sigaction -  { -    /* Signal handler. */ +struct sigaction {  #ifdef __USE_POSIX199309 -    union -      { -	/* Used if SA_SIGINFO is not set.  */ -	__sighandler_t sa_handler; -	/* Used if SA_SIGINFO is set.  */ -	void (*sa_sigaction) (int, siginfo_t *, void *); -      } -    __sigaction_handler; -# define sa_handler	__sigaction_handler.sa_handler -# define sa_sigaction	__sigaction_handler.sa_sigaction +	union { +		__sighandler_t sa_handler; +		void (*sa_sigaction)(int, siginfo_t *, void *); +	} __sigaction_handler; +# define sa_handler     __sigaction_handler.sa_handler +# define sa_sigaction   __sigaction_handler.sa_sigaction  #else -    __sighandler_t sa_handler; +	__sighandler_t  sa_handler;  #endif - -    /* Additional set of signals to be blocked.  */ -    __sigset_t sa_mask; - -    /* Special flags.  */ -    unsigned long sa_flags; - -    /* Not used by Linux/Sparc yet.  */ -    void (*sa_restorer) (void); -  }; +	unsigned long   sa_flags; +	void            (*sa_restorer)(void); +	sigset_t        sa_mask; +};  /* Bits in `sa_flags'.  */ diff --git a/libc/sysdeps/linux/x86_64/sigaction.c b/libc/sysdeps/linux/x86_64/sigaction.c index 58466c8ef..d1adbc4be 100644 --- a/libc/sysdeps/linux/x86_64/sigaction.c +++ b/libc/sysdeps/linux/x86_64/sigaction.c @@ -25,9 +25,6 @@  #include <sys/syscall.h> -/* The difference here is that the sigaction structure used in the -   kernel is not the same as we use in the libc.  Therefore we must -   translate it here.  */  #include <bits/kernel_sigaction.h>  /* We do not globally define the SA_RESTORER flag so do it here.  */ @@ -35,64 +32,47 @@  extern __typeof(sigaction) __libc_sigaction; +  #ifdef __NR_rt_sigaction +  /* Using the hidden attribute here does not change the code but it     helps to avoid warnings.  */ -extern void restore_rt (void) __asm__ ("__restore_rt") attribute_hidden; -extern void restore (void) __asm__ ("__restore") attribute_hidden; - -/* Experimentally off - libc_hidden_proto(memcpy) */ +extern void restore_rt(void) __asm__ ("__restore_rt") attribute_hidden; +extern void restore(void) __asm__ ("__restore") attribute_hidden;  /* If ACT is not NULL, change the action for SIG to *ACT.     If OACT is not NULL, put the old action for SIG in *OACT.  */  int -__libc_sigaction (int sig, const struct sigaction *act, struct sigaction *oact) +__libc_sigaction(int sig, const struct sigaction *act, struct sigaction *oact)  { -	int result; -	struct kernel_sigaction kact, koact; -	enum { -		SIGSET_MIN_SIZE = sizeof(kact.sa_mask) < sizeof(act->sa_mask) -				? sizeof(kact.sa_mask) : sizeof(act->sa_mask) -	}; +	struct sigaction kact;  	if (act) { -		kact.k_sa_handler = act->sa_handler; -		memcpy (&kact.sa_mask, &act->sa_mask, SIGSET_MIN_SIZE); -		kact.sa_flags = act->sa_flags | SA_RESTORER; - +		memcpy(&kact, act, sizeof(kact)); +		kact.sa_flags |= SA_RESTORER;  		kact.sa_restorer = &restore_rt; +		act = &kact;  	} -  	/* NB: kernel (as of 2.6.25) will return EINVAL -	 * if sizeof(kact.sa_mask) does not match kernel's sizeof(sigset_t) */ -	result = INLINE_SYSCALL (rt_sigaction, 4, sig, -	                act ? &kact : NULL, -	                oact ? &koact : NULL, -			sizeof(kact.sa_mask)); - -	if (oact && result >= 0) { -		oact->sa_handler = koact.k_sa_handler; -		memcpy (&oact->sa_mask, &koact.sa_mask, SIGSET_MIN_SIZE); -		oact->sa_flags = koact.sa_flags; -		oact->sa_restorer = koact.sa_restorer; -	} -	return result; +	 * if sizeof(act->sa_mask) does not match kernel's sizeof(sigset_t) */ +	return INLINE_SYSCALL(rt_sigaction, 4, sig, act, oact, sizeof(act->sa_mask));  } +  #else -extern void restore (void) __asm__ ("__restore") attribute_hidden; +extern void restore(void) __asm__ ("__restore") attribute_hidden;  /* If ACT is not NULL, change the action for SIG to *ACT.     If OACT is not NULL, put the old action for SIG in *OACT.  */  int -__libc_sigaction (int sig, const struct sigaction *act, struct sigaction *oact) +__libc_sigaction(int sig, const struct sigaction *act, struct sigaction *oact)  {  	int result;  	struct old_kernel_sigaction kact, koact;  #ifdef SIGCANCEL  	if (sig == SIGCANCEL) { -		__set_errno (EINVAL); +		__set_errno(EINVAL);  		return -1;  	}  #endif @@ -103,18 +83,16 @@ __libc_sigaction (int sig, const struct sigaction *act, struct sigaction *oact)  		kact.sa_flags = act->sa_flags | SA_RESTORER;  		kact.sa_restorer = &restore;  	} - -	__asm__ __volatile__ ("syscall\n" -	              : "=a" (result) -	              : "0" (__NR_sigaction), "mr" (sig), -	                "c" (act ? &kact : 0), -	                "d" (oact ? &koact : 0)); - +	__asm__ __volatile__ ( +		"syscall\n" +		: "=a" (result) +		: "0" (__NR_sigaction), "mr" (sig), +		  "c" (act ? &kact : NULL), +		  "d" (oact ? &koact : NULL));  	if (result < 0) {  		__set_errno(-result);  		return -1;  	} -  	if (oact) {  		oact->sa_handler = koact.k_sa_handler;  		oact->sa_mask.__val[0] = koact.sa_mask; @@ -123,14 +101,16 @@ __libc_sigaction (int sig, const struct sigaction *act, struct sigaction *oact)  	}  	return result;  } +  #endif +  #ifndef LIBC_SIGACTION -/* libc_hidden_proto(sigaction) */  weak_alias(__libc_sigaction,sigaction)  libc_hidden_weak(sigaction)  #endif +  /* NOTE: Please think twice before making any changes to the bits of     code below.  GDB needs some intimate knowledge about it to     recognize them as signal trampolines, and make backtraces through @@ -139,18 +119,19 @@ libc_hidden_weak(sigaction)     If you ever feel the need to make any changes, please notify the     appropriate GDB maintainer.  */ -#define RESTORE(name, syscall) RESTORE2 (name, syscall) -# define RESTORE2(name, syscall) \ -__asm__ (					\ -   ".text\n"					\ -   "__" #name ":\n"				\ -   "	movq $" #syscall ", %rax\n"		\ -   "	syscall\n"				\ -   ); +#define RESTORE(name, syscall) RESTORE2(name, syscall) +#define RESTORE2(name, syscall) \ +__asm__ (						\ +	".text\n"					\ +	"__" #name ":\n"				\ +	"	movq	$" #syscall ", %rax\n"		\ +	"	syscall\n"				\ +); +  #ifdef __NR_rt_sigaction  /* The return code for realtime-signals.  */ -RESTORE (restore_rt, __NR_rt_sigreturn) +RESTORE(restore_rt, __NR_rt_sigreturn)  #endif  #ifdef __NR_sigreturn -RESTORE (restore, __NR_sigreturn) +RESTORE(restore, __NR_sigreturn)  #endif diff --git a/libc/sysdeps/linux/xtensa/sigaction.c b/libc/sysdeps/linux/xtensa/sigaction.c index 123cb5085..302d13305 100644 --- a/libc/sysdeps/linux/xtensa/sigaction.c +++ b/libc/sysdeps/linux/xtensa/sigaction.c @@ -15,52 +15,25 @@  #define SA_RESTORER	0x04000000 -extern void __default_sa_restorer (void); +extern void __default_sa_restorer(void); -/* Experimentally off - libc_hidden_proto(memcpy) */ - -int __libc_sigaction (int signum, const struct sigaction *act, +int __libc_sigaction(int sig, const struct sigaction *act,  					  struct sigaction *oact)  { -	struct kernel_sigaction kact, koact; -	int result; -	enum { -		SIGSET_MIN_SIZE = sizeof(kact.sa_mask) < sizeof(act->sa_mask) -				? sizeof(kact.sa_mask) : sizeof(act->sa_mask) -	}; - -	if (act) { -		kact.k_sa_handler = act->sa_handler; -		memcpy(&kact.sa_mask, &act->sa_mask, SIGSET_MIN_SIZE); -		kact.sa_flags = act->sa_flags; +	struct sigaction kact; -		if (kact.sa_flags & SA_RESTORER) { -			kact.sa_restorer = act->sa_restorer; -		} else { -			kact.sa_restorer = __default_sa_restorer; -			kact.sa_flags |= SA_RESTORER; -		} +	if (act && !(act->sa_flags & SA_RESTORER)) { +		memcpy(&kact, act, sizeof(kact)); +		kact.sa_restorer = __default_sa_restorer; +		kact.sa_flags |= SA_RESTORER; +		act = &kact;  	} -  	/* NB: kernel (as of 2.6.25) will return EINVAL -	 * if sizeof(kact.sa_mask) does not match kernel's sizeof(sigset_t) */ -	result = __syscall_rt_sigaction(signum, -			act ? &kact : NULL, -			oact ? &koact : NULL, -			sizeof(kact.sa_mask)); - -	if (oact && result >= 0) { -		oact->sa_handler = koact.k_sa_handler; -		memcpy(&oact->sa_mask, &koact.sa_mask, SIGSET_MIN_SIZE); -		oact->sa_flags = koact.sa_flags; -		oact->sa_restorer = koact.sa_restorer; -	} - -	return result; +	 * if sizeof(act->sa_mask) does not match kernel's sizeof(sigset_t) */ +	return __syscall_rt_sigaction(sig, act, oact, sizeof(act->sa_mask));  }  #ifndef LIBC_SIGACTION -libc_hidden_proto(sigaction)  weak_alias(__libc_sigaction, sigaction)  libc_hidden_weak(sigaction)  #endif diff --git a/libpthread/linuxthreads/sysdeps/pthread/sigaction.c b/libpthread/linuxthreads/sysdeps/pthread/sigaction.c index 0a0a9e29f..2f2a85caf 100644 --- a/libpthread/linuxthreads/sysdeps/pthread/sigaction.c +++ b/libpthread/linuxthreads/sysdeps/pthread/sigaction.c @@ -17,6 +17,8 @@     Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA     02111-1307 USA.  */ +/* Somebody please explain what's going on here.  --vda */ +  /* This is tricky.  GCC doesn't like #include_next in the primary     source file and even if it did, the first #include_next is this     exact file anyway.  */  | 
