On Fri, 12 Aug 2005, Chris Wright wrote: > * Jan Engelhardt ([EMAIL PROTECTED]) wrote: > > So, if in doubt what is really meant - check which of the two/three/+ > > different behaviors the users out there favor most. > > Rather, check what happens in practice on other implementations. I don't > have Solaris, HP-UX, Irix, AIX, etc. boxen at hand, but some folks must. >
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. -- 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); } /* * 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); }