2010年5月30日 星期日

How to use sigsuspend() to wait the signal

//Reference:http://www.gnu.org/s/libc/manual/html_node/Sigsuspend.html#Sigsuspend
#include <&stdio.h&>
#include <&stdlib.h&>
#include <&string.h&>
#include <&unistd.h&>
#include <&signal.h&>
static int g_bTerminate=0;

static void register_signal(int signum, void (*handler)(int))
{
struct sigaction sigaInst;
sigset_t block_mask;
//Initializes the signal set set to include all of the defined signals.
sigfillset (&block_mask);
if(signum != SIGALRM)
{
sigaInst.sa_flags = SA_RESTART;
}
sigaInst.sa_handler = handler;
/*
sigset_t sa_mask

This specifies a set of signals to be blocked while the handler runs. Blocking is explained in Blocking for Handler. Note that the signal that was delivered is automatically blocked by default before its handler is started; this is true regardless of the value in sa_mask. If you want that signal not to be blocked within its handler, you must write code in the handler to unblock it.
*/
sigaInst.sa_mask=block_mask;

sigaction(signum, &sigaInst, NULL);
}

static void ctrl_sighandler(int signo)
{
printf("enter signal handler...!\n");
if (signo == SIGTERM)
{
g_bTerminate = 1;
}
}


int main(){

sigset_t mask, oldmask;
sigset_t block_mask;
//The user can use "kill -15 XXX" to terminate the progarm.
register_signal(SIGTERM, ctrl_sighandler);


sigemptyset(&block_mask);
//Block SIGQUIT (Terminal quit (POSIX)). The user can not use "Ctrl+\" to terminate the procgram.
sigaddset(&block_mask,SIGQUIT);
//Block SIGINT (Terminal interrupt (ANSI)). The user can not use "Ctrl+C" to terminate the procgram.
sigaddset(&block_mask, SIGINT);
sigprocmask (SIG_BLOCK, &block_mask, NULL);

/* Set up the mask of signals to temporarily block. */
sigemptyset (&mask);
sigaddset (&mask, SIGTERM);

//daemon(0, 0);

//Wait for SIGTERM arriving...
//1. temporarily block SIGTERM
sigprocmask (SIG_BLOCK, &mask, &oldmask);
while (g_bTerminate == 0)
sigsuspend (&oldmask);//2. SIGTERM is not in oldmask. So when one signal arrivies, sigsuspend() return. And then check g_bTerminate. If the signal is SIGTERM, the g_bTerminate will be set as 1. So the while-loop is break.
sigprocmask (SIG_UNBLOCK, &mask, NULL);//3. Remove SIGTERM from the block list.
printf("main() has been terminated....\n");
return 0;
}

1 則留言:

匿名 提到...

At this time I am going away to do my breakfast, later than having my breakfast
coming over again to read more news.

Here is my site ... bankruptcy laws in florida