/* * complex_signal.c * This program demonstrates how to set a signal and then * how to send one using the sigaction function. * * to compile: gcc -O -pipe signal_alert.c -o signal_alert.c */ #include #include #include #include #include #include /* declare our signal handler */ void complex(int sig, siginfo_t *info, void *context); int main(int argc, char **argv) { int sig; pid_t child; struct sigaction act; /* double check our args */ if( argc > 1 ) { sig = atoi(argv[1]); child = fork(); /* child */ if( child == 0 ) { /* * Note that the sa_sigaction is defined for * ease of use. The real member would be: * * act.__sigaction_u.__sa_sigaction */ memset(&act, 0, sizeof(struct sigaction)); act.sa_sigaction = complex; act.sa_flags |= SA_SIGINFO; /* now set the sa_mask */ sigemptyset(&act.sa_mask); sigfillset(&act.sa_mask); /* remove our signal from the set */ sigdelset(&act.sa_mask, sig); printf("Child setting the signal handler \n"); /* set the signal handler */ sigaction(sig, &act, (struct sigaction *)NULL); /* sleep untill we get a signal */ sleep(100000); } else { /* parent */ sleep(3); printf("Parent sending signal [ %d ] to PID [ %d ]\n", sig, child); kill(child, sig); } } /* if(argc) */ /* FIN */ return(0); } /* * complex * Note that although FreeBSD does support the SA_SIGINFO flag, the * siginfo_t strucutre does not really get filled out. Most of the * values are zero and is used for compatibility. Currently * this is true for almost all of the BSDs. You should check your * system because this could change and full support could be added. */ void complex(int sig, siginfo_t *info, void *context) { if( info ) { /* * All should be zero except for si_signo */ printf("Signal recieved\n"); printf("\n code [%d]\n error [%d]\n sig no [%d] \n uid [%d] \n status [%d] \n pid [%d]\n", info->si_code, info->si_errno, info->si_signo, info->si_uid, info->si_status, info->si_pid ); } }