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