/*
 * 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 <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <signal.h>
#include <unistd.h>


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



syntax highlighted by Code2HTML, v. 0.9