Re: Signal handling possibly wrong

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

 



On Tue, 2005-08-09 at 21:41 +0200, Bodo Stroesser wrote:
> S
> > To me, the man pages make more sense, and I think the kernel is wrong.
> 
> Yes, that's what I think, too. If someone doesn't want additional signals
> to be masked, he can set sa_mask to be empty.
> OTOH, I have no idea, what POSIX specifies. Maybe kernel is right and man
> page is wrong?
> 
> 	Bodo
> > 

Man pages and kernel are right.  I just tested this out on 2.6.13-rc3
with the attached program and it seems to follow what is stated in the
man pages. So the assumption of what the code did by looking at it
proves to be the mistake. :-)

Conclusion:  sa_mask defers the signals. SA_NODEFER defers the sent
signal.

-- Steve

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <sys/types.h>
#include <unistd.h>

void user1(int x)
{
	int pid = getpid();
	printf("pid[%d]: user1 start\n",pid);
	sleep(5);
	printf("pid[%d]: user1 stopped\n",pid);
}

void user2(int x)
{
	int pid = getpid();
	printf("pid[%d]:in user2\n",pid);
}

void intr(int x)
{
	int pid = getpid();
	printf("pid[%d]: received SIGINT\n",pid);
	exit(0);
}

void start1(void)
{
	struct sigaction act;

	memset(&act,0,sizeof(act));

	act.sa_handler = intr;
	if ((sigaction(SIGINT,&act,NULL)) < 0) {
		perror("child1: sigaction");
		exit(-1);
	}
		
	act.sa_handler = user1;
	sigaddset(&act.sa_mask,SIGUSR2);
	if ((sigaction(SIGUSR1,&act,NULL)) < 0) {
		perror("child1: sigaction");
		exit(-1);
	}

	act.sa_handler = user2;
	if ((sigaction(SIGUSR2,&act,NULL)) < 0) {
		perror("child1: sigaction");
		exit(-1);
	}
		
		
	for (;;)
		;

}

void start2(void)
{
	struct sigaction act;

	memset(&act,0,sizeof(act));
	
	act.sa_handler = intr;
	if ((sigaction(SIGINT,&act,NULL)) < 0) {
		perror("child2: sigaction");
		exit(-1);
	}
		
	act.sa_handler = user1;
	act.sa_flags |= SA_NODEFER;
	if ((sigaction(SIGUSR1,&act,NULL)) < 0) {
		perror("child2: sigaction");
		exit(-1);
	}
		
	act.sa_handler = user2;
	if ((sigaction(SIGUSR2,&act,NULL)) < 0) {
		perror("child1: sigaction");
		exit(-1);
	}
		
	for (;;)
		;

}

int main(int argc, char **argv)
{
	int pid[2];

	if ((pid[0] = fork()) < 0) {
		perror("fork");
	} else if (!pid[0]) {
		start1();
		exit(0);
	}
	
	if ((pid[1] = fork()) < 0) {
		perror("fork");
	} else if (!pid[1]) {
		start2();
		exit(0);
	}

	printf("parent sending %d SIGUSR1\n",pid[0]);
	kill(pid[0],SIGUSR1);
	sleep(1);
	printf("parent sending %d SIGUSR2\n",pid[0]);
	kill(pid[0],SIGUSR2);
	sleep(5);
	printf("parent sending %d SIGUSR1\n",pid[0]);
	kill(pid[0],SIGUSR1);
	sleep(1);
	printf("parent sending %d SIGUSR1\n",pid[0]);
	kill(pid[0],SIGUSR1);
	sleep(1);
	printf("parent sending %d SIGINT\n",pid[0]);
	kill(pid[0],SIGINT);

	printf("parent sending %d SIGUSR1\n",pid[1]);
	kill(pid[1],SIGUSR1);
	sleep(1);
	printf("parent sending %d SIGUSR2\n",pid[1]);
	kill(pid[1],SIGUSR2);
	sleep(5);
	printf("parent sending %d SIGUSR1\n",pid[1]);
	kill(pid[1],SIGUSR1);
	sleep(1);
	printf("parent sending %d SIGUSR1\n",pid[1]);
	kill(pid[1],SIGUSR1);
	sleep(1);
	printf("parent sending %d SIGINT\n",pid[1]);
	kill(pid[1],SIGINT);

	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