Re: [PATCH] Fix PPC signal handling of NODEFER, should not affectsa_mask
From: Steven Rostedt
Date: Fri Aug 12 2005 - 14:28:30 EST
On Fri, 12 Aug 2005, Steven Rostedt wrote:
>
> I've supplied this before, but I'll send it again. Attached is a program
> that should show the behavior of the sigaction. If someone has one of the
> above mentioned boxes, please run this on the box and send back the
> results.
Here it is again. I tried it on another Linux box and realize that the
parent was running before the child was able to initialize the signal
handlers. So I added another sleep. I know sleeps don't guarentee
anything, but this is just a simple test.
Attached is the fixed program.
-- Steve#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
static int u1;
static int u2;
static void user1(int x)
{
/* for testing against itself */
if (u1)
u2 = 1;
u1 = 1;
sleep(5);
u1 = 0;
}
static void user2(int x)
{
if (u1)
u2 = 1;
}
static void intr(int x)
{
exit(u2);
}
static void start(struct sigaction *act)
{
struct sigaction a;
memset(&a,0,sizeof(a));
a.sa_handler = intr;
if ((sigaction(SIGINT,&a,NULL)) < 0) {
perror("sigaction");
exit(-1);
}
/*
* This is the testing handler
*/
act->sa_handler = user1;
if ((sigaction(SIGUSR1,act,NULL)) < 0) {
perror("sigaction");
exit(-1);
}
a.sa_handler = user2;
if ((sigaction(SIGUSR2,&a,NULL)) < 0) {
perror("sigaction");
exit(-1);
}
for (;;)
;
}
int testsig(struct sigaction *act, int sig1, int sig2)
{
int pid;
int status;
if ((pid = fork()) < 0) {
perror("fork");
} else if (!pid) {
/*
* Test1 sa_mask includes SIGUSR2
*/
start(act);
exit(0);
}
sleep(1);
/*
* Send first signal to start the test.
*/
kill(pid,sig1);
/*
* SIGUSR1 sleeps for 5, just sleep for on here
* to make sure the system got it.
*/
sleep(1);
/*
* Send the second signal to the child, to see if
* this wakes it up.
*/
kill(pid,sig2);
sleep(1);
/*
* End the test.
*/
kill(pid,SIGINT);
waitpid(pid,&status,0);
return WEXITSTATUS(status);
}
int main(int argc, char **argv)
{
struct sigaction act;
int ret;
memset(&act,0,sizeof(act));
sigaddset(&act.sa_mask,SIGUSR2);
ret = testsig(&act,SIGUSR1,SIGUSR2);
switch (ret) {
case 0:
printf("sa_mask blocks other signals\n");
break;
case 1:
printf("sa_mask does not block other signals\n");
break;
default:
printf("Unknown return code!!\n");
}
memset(&act,0,sizeof(act));
act.sa_flags |= SA_NODEFER;
ret = testsig(&act,SIGUSR1,SIGUSR2);
switch (ret) {
case 0:
printf("SA_NODEFER blocks other signals\n");
break;
case 1:
printf("SA_NODEFER does not block other signals\n");
break;
default:
printf("Unknown return code!!\n");
}
memset(&act,0,sizeof(act));
act.sa_flags |= SA_NODEFER;
sigaddset(&act.sa_mask,SIGUSR2);
ret = testsig(&act,SIGUSR1,SIGUSR2);
switch (ret) {
case 0:
printf("SA_NODEFER does not affect sa_mask\n");
break;
case 1:
printf("SA_NODEFER affects sa_mask\n");
break;
default:
printf("Unknown return code!!\n");
}
memset(&act,0,sizeof(act));
act.sa_flags |= SA_NODEFER;
sigaddset(&act.sa_mask,SIGUSR1);
ret = testsig(&act,SIGUSR1,SIGUSR1);
switch (ret) {
case 0:
printf("SA_NODEFER and sa_mask blocks sig\n");
break;
case 1:
printf("SA_NODEFER and sa_mask does not block sig\n");
break;
default:
printf("Unknown return code!!\n");
}
memset(&act,0,sizeof(act));
ret = testsig(&act,SIGUSR1,SIGUSR1);
switch (ret) {
case 0:
printf("!SA_NODEFER blocks sig\n");
break;
case 1:
printf("!SA_NODEFER does not block sig\n");
break;
default:
printf("Unknown return code!!\n");
}
memset(&act,0,sizeof(act));
memset(&act,0,sizeof(act));
act.sa_flags |= SA_NODEFER;
ret = testsig(&act,SIGUSR1,SIGUSR1);
switch (ret) {
case 0:
printf("SA_NODEFER blocks sig\n");
break;
case 1:
printf("SA_NODEFER does not block sig\n");
break;
default:
printf("Unknown return code!!\n");
}
memset(&act,0,sizeof(act));
sigaddset(&act.sa_mask,SIGUSR1);
ret = testsig(&act,SIGUSR1,SIGUSR1);
switch (ret) {
case 0:
printf("sa_mask blocks sig\n");
break;
case 1:
printf("sa_mask does not block sig\n");
break;
default:
printf("Unknown return code!!\n");
}
exit(0);
}