Re: [PATCH] Fix PPC signal handling of NODEFER, should not affectsa_mask

From: Steven Rostedt
Date: Fri Aug 12 2005 - 16:08:59 EST


On Fri, 2005-08-12 at 21:31 +0200, Jesper Juhl wrote:

> >
> I've got a 4-way pSeries p550 running AIX 5.3 here :
>
> $ uname -s -M -p -v -r
> AIX 3 5 powerpc IBM,9113-550
>
> Output from your program :
>
> $ ./a.out
> Unknown return code!!
> Unknown return code!!
> Unknown return code!!
> Unknown return code!!
> Unknown return code!!
> Unknown return code!!
> sa_mask blocks sig
>

Did you try my updated code (the one with the extra sleep?). Here's
another version where I output the unknown return code. Funny that this
didn't print any other error message. Since the return codes should show
something else.

Please try the attached.

Thanks,

-- 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 (%d)!!\n",ret);
}

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 (%d)!!\n",ret);
}

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 (%d)!!\n",ret);
}

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 (%d)!!\n",ret);
}

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 (%d)!!\n",ret);
}

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 (%d)!!\n",ret);
}

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 (%d)!!\n",ret);
}

exit(0);
}