日期:2014-05-16  浏览次数:20709 次

_XOPEN_SOURCE宏能够改变signal函数的行为,这是如何做到的?

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

void sig_int(int signo)
{
    printf("caught SIGINT\n");
}

int main()
{
    signal(SIGINT, sig_int);
    for (; ; );

    return 0;
}

默认情况下,如果输入多个中断键,那么能够捕捉所有的中断信号。
但是如果用 gcc test.c -D _XOPEN_SOURCE 编译,那么只能捕捉一次中断信号,当输入第二个中断键时程序就退出了。
请问_XOPEN_SOURCE 这个宏是如何做到改变signal函数的行为的,就我理解,这些宏定义不是最多只能让程序多包含一些特定的函数声明吗?

------解决方案--------------------
信号很复杂,用signal会遇到很多的移植性和可靠性的问题,建议使用sigaction;
至于楼主遇到的情况,在Linux函数手册中有详细的描述

PORTABILITY
       The  original  Unix  signal()  would reset the handler to SIG_DFL, and System V (and the Linux kernel and
       libc4,5) does the same.  On the other hand, BSD does not reset the handler, but blocks new  instances  of
       this signal from occurring during a call of the handler.  The glibc2 library follows the BSD behaviour.

       If  one  on  a  libc5  system includes <bsd/signal.h> instead of <signal.h> then signal() is redefined as
       __bsd_signal and signal has the BSD semantics. This is not recommended.

       If one on a glibc2 system defines a feature test macro such as _XOPEN_SOURCE or uses a separate sysv_sig-
       nal function, one obtains classical behaviour. This is not recommended.

       Trying  to  change the semantics of this call using defines and includes is not a good idea. It is better
       to avoid signal() altogether, and use sigaction(2) instead.