blob: 658c3ad5854d187c691a5e8e766adac3cab55ae7 [file] [log] [blame]
/*
* sigaction.c
*/
#include <signal.h>
#include <sys/syscall.h>
#include <klibc/sysconfig.h>
__extern void __sigreturn(void);
__extern int __sigaction(int, const struct sigaction *, struct sigaction *);
#ifdef __sparc__
__extern int __rt_sigaction(int, const struct sigaction *, struct sigaction *,
void (*)(void), size_t);
#else
__extern int __rt_sigaction(int, const struct sigaction *, struct sigaction *,
size_t);
#endif
int sigaction(int sig, const struct sigaction *act, struct sigaction *oact)
{
int rv;
#if _KLIBC_NEEDS_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
#if _KLIBC_USE_RT_SIG
# ifdef __sparc__
{
void (*restorer)(void);
restorer = (act && act->sa_flags & SA_RESTORER)
? (void (*)(void))((uintptr_t)act->sa_restorer - 8)
: NULL;
rv = __rt_sigaction(sig, act, oact, restorer, sizeof(sigset_t));
}
# else
rv = __rt_sigaction(sig, act, oact, sizeof(sigset_t));
# endif
#else
rv = __sigaction(sig, act, oact);
#endif
#if _KLIBC_NEEDS_SA_RESTORER
if (oact && (oact->sa_restorer == &__sigreturn)) {
oact->sa_flags &= ~SA_RESTORER;
}
#endif
return rv;
}