blob: 85f42a244cc65ff7d65f6bde9a21a8c1e146aadb [file] [log] [blame]
/*
* sigaction.c
*/
#include <signal.h>
#include <sys/syscall.h>
__extern void __sigreturn(void);
__extern int __sigaction(int, const struct sigaction *, struct sigaction *);
__extern int __rt_sigaction(int, const struct sigaction *, struct sigaction *, size_t);
int sigaction(int sig, const struct sigaction *act, struct sigaction *oact)
{
int rv;
#if defined(__i386__) || defined(__x86_64__)
/* x86-64, and the Fedora i386 kernel, are broken without SA_RESTORER */
struct sigaction sa;
if ( act && !(act->sa_flags & SA_RESTORER) ) {
sa = *act;
act = &sa;
/* The kernel can't be trusted to have a valid default restorer */
sa.sa_flags |= SA_RESTORER;
sa.sa_restorer = &__sigreturn;
}
#endif
#ifdef __NR_sigaction
rv = __sigaction(sig, act, oact);
#else
rv = __rt_sigaction(sig, act, oact, sizeof(sigset_t));
#endif
#if defined(__i386__) || defined(__x86_64__)
if ( oact && (oact->sa_restorer == &__sigreturn) ) {
oact->sa_flags &= ~SA_RESTORER;
}
#endif
return rv;
}