X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=klibc%2Fklibc%2Fsigaction.c;h=85f42a244cc65ff7d65f6bde9a21a8c1e146aadb;hb=972d318a3123b00d0ed6b78bbcf70a0965841a8e;hp=ebd34710f18ec0f7db8090a60cbbc38eeb4fa351;hpb=a41a0e28c2ba0abf99b5e7ea17645ae0e4f05758;p=elogind.git diff --git a/klibc/klibc/sigaction.c b/klibc/klibc/sigaction.c index ebd34710f..85f42a244 100644 --- a/klibc/klibc/sigaction.c +++ b/klibc/klibc/sigaction.c @@ -5,15 +5,40 @@ #include #include -#ifdef __NR_sigaction +__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; -_syscall3(int,sigaction,int,sig,const struct sigaction *,act,struct sigaction *,oact); +#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 -int sigaction(int sig, const struct sigaction *act, struct sigaction *oact) -{ - return rt_sigaction(sig, act, oact, sizeof(sigset_t)); -} +#if defined(__i386__) || defined(__x86_64__) + if ( oact && (oact->sa_restorer == &__sigreturn) ) { + oact->sa_flags &= ~SA_RESTORER; + } #endif + + return rv; +}