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);
}