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

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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

[Index of Archives]     [Kernel Newbies]     [Netfilter]     [Bugtraq]     [Photo]     [Gimp]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Video 4 Linux]     [Linux for the blind]
  Powered by Linux