Linux Signal (8): sigsetjmp和siglongjmp

进程部分介绍过了setjmp和longjmp函数, 这两个函数在跳转时会带信号屏蔽字跳转, 在信号处理程序(hanlder)中使用longjmp会导致后来产生的这种信号被屏蔽.

POSIX.1 也没有具体说明setjmp和longjmp对信号屏蔽字的作用, 而是定义了两个新函数: sigsetjmp和siglongjmp.

1. 原型:

#include  < setjmp.h >

int  sigsetjmp(sigjmp_buf env,  int  savemask);
直接调用则返回0, 从siglongjmp调用返回则返回非0值.

void  siglongjmp(sigjmp_buf env,  int  val);

可见发现sigsetjmp比setjmp多了一个参数savemask, 如果非0, 则sigsetjmp在env中保存进程的当前信号屏蔽字.

2. 实例:

还是老习惯, 用代码来验证

#include  < signal.h >
#include 
< setjmp.h >
#include 
< stdio.h >
#include 
< stdlib.h >

/*  Jump buffer  */
static  sigjmp_buf jmpbuf;

/*  Signal handler  */
static   void  myfunc( int  signo)
{
    printf(
" SIGQUIT " );
    sleep(
1 );
    siglongjmp(jmpbuf, 
1 );
}

int  main()
{
    
char   * =  NULL;
    
struct  sigaction act;
    act.sa_handler 
=  myfunc;
    act.sa_flags 
=  SA_INTERRUPT;
    sigemptyset(
& act.sa_mask);

    
if  (sigaction(SIGQUIT,  & act, NULL)  <   0 )
        perror(
" sigaction " );

    
if  (sigsetjmp(jmpbuf,  1 ==   1 )
    {
        printf(
" I'm jumped " );
    }
    
else
    {
        
/*  SIGSEGV  */
        raise(SIGQUIT);
    }

    
/*  JUMP  */
    printf(
" I'm here " );

    
return   0 ;
}

这段代码首先用sigaction设定SIGQUIT信号的处理函数, 然后sigsetjmp设定sigjmp_buf, 当它从siglongjmp返回时显示I'm jumped, 第一次设定完成后产生SIGQUIT信号.

运行结果:

SIGQUIT
I'm jumped
I'm here

你可能感兴趣的:(Linux Signal (8): sigsetjmp和siglongjmp)