Surely it isn't supposed to work like this?
The reason is that neither sys_sigaction, nor do_signal check the
sa_mask for
these signals, while send_sig_info always checks against t->blocked
before
setting t->sigpending to 1 (kernel/signal.c, lines 341-2).
The fix is trivial: (I hope. I haven't tested it since I would have to
upgrade
to 2.1.92, which is causing me trouble. (I'm starting to suspect my
compiler.))
--- signal.c Sun Apr 5 17:30:52 1998
+++ signal.c Sun Apr 5 17:36:32 1998
@@ -788,6 +788,9 @@
if (act) {
*k = *act;
+ /* Don't let the user block SIGKILL or SIGSTOP
+ * even while handling a signal. */
+ k->sa.sa_mask.sig[0] &= ~(SIGKILL | SIGSTOP);
/*
* POSIX 3.3.1.3:
A program to demonstrate this problem follows. Once you have run it, it
can't
bekilled. I suggest renicing it to 20 until you can reboot.
Andrew Lewycky
alewycky@globalserve.net
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
void handler(int dummy)
{
printf("in handler\n");
while (1) ;
}
int main(int argc, char *argv[])
{
struct sigaction newsig, oldsig;
newsig.sa_handler = handler;
newsig.sa_flags = SA_RESTART;
sigfillset(&newsig.sa_mask);
newsig.sa_restorer = NULL;
sigaction(SIGUSR1, &newsig, &oldsig);
raise(SIGUSR1);
return 0;
}
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu