English 中文(简体)
XOOPEN_SOFORS和信号处理
原标题:XOPEN_SOURCE and signal handling

在下面的程序中,如果我不注意 XOPEN_SOURCE 线, 当我点击 C-c 时, 我的程序就会终止, 如果我不评论该行, 同样的程序就不会终止 。 有人知道 XOPEN_SOURCE 如何影响信号处理? 我用 gcc (4. 6. 3) 和 glibc (2. 15) 在 Linux 上 使用 gcc (4. 6.3) 和 glibc (2. 15) 。

/* #define _XOPEN_SOURCE 700 */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>

typedef void (*sighandler_t)(int);

void handle_signal(int signo)
{
    printf("
[MY_SHELL] ");
    fflush(stdout);
}

int main()
{
    int c;
    signal(SIGINT, SIG_IGN);
    signal(SIGINT, handle_signal);
    printf("[MY_SHELL] ");
    while ((c = getchar()) != EOF) {
        if (c ==  
 )
            printf("[MY_SHELL] ");
    }
    printf("
");
    return 0;
}
最佳回答

问题在于, ignal () 函数在安装信号处理功能时可以有两种不同的行为形式:

  • System V semantics, where the signal handler is "one-shot" - that is, after the signal handling function is called, the signal s disposition is reset to SIG_DFL - and system calls that are interrupted by the signal are not restarted; or
  • BSD semantics, where the signal handler is not reset when the signal fires, the signal is blocked whilst the signal handler is executing, and most interrupted system calls are automatically restarted.

在使用 glibc 的 Linux 上, 如果定义了 < code\\ bSD_ SOURC , 则您可以得到 BSD 语义学, 如果没有定义, 系统V 语义学。 默认定义了 < code\ bSD_ SOURCE 宏, 但是如果定义了 < code\ XOPEN_ SOURCE (或者其他一些宏, 如 < code\\ posix_ SOURCE 和 ,, 则该默认定义被抑制 。

在系统V的语义学下,如果 read () system call inside getchar () SIGINT 中断,那么 () read () read() ) read() read > read reproduct 将返回 < EOF , 设置为 (这会使您的程序正常退出)。此外,在第一个 sING 之后,该信号的处置将重新设置为默认,而 的默认动作是终止程序(即使您的程序在第一个 < code > < sIGINT < /code > /code > 中幸存下来,第二个也会导致它异常退出)。

解决方案是不使用 ignal () 来安装信号处理功能; 相反, 您应该使用 < code> sigaction () , 这是便携式的 -- 它给各地的语义都是一样的。 在 sa_flags 设置为 SA_RESTART , sigaction () 中, 它会给 BSD 语义, 这是你想要的 。

问题回答

这些微妙的差别在于为什么通常偏爱 sigprocmask () 而不是 ignal () <() <() <() 。 具有 定义的调用(以 sttrace 显示)

rt_sigaction(SIGINT, {SIG_IGN, [], SA_INTERRUPT|SA_NODEFER|SA_RESETHAND}, {SIG_DFL, [], 0}, 8) = 0
rt_sigaction(SIGINT, {0x80484dc, [], SA_INTERRUPT|SA_NODEFER|SA_RESETHAND}, {SIG_IGN, [], SA_INTERRUPT|SA_NODEFER|SA_RESETHAND}, 8) = 0

被评论的一通呼声:

rt_sigaction(SIGINT, {SIG_IGN, [INT], SA_RESTART}, {SIG_DFL, [], 0}, 8) = 0 
rt_sigaction(SIGINT, {0x80484dc, [INT], SA_RESTART}, {SIG_IGN, [INT], SA_RESTART}, 8) = 0

缺少的重要额外旗帜是 SA_RESTART ,它允许 read 系统继续呼唤,仿佛没有信号发生。 否则,系统呼叫表示失败, getchar () return -1 (但表示失败,而不是真正的 EOF), 程序终止 。





相关问题
Fastest method for running a binary search on a file in C?

For example, let s say I want to find a particular word or number in a file. The contents are in sorted order (obviously). Since I want to run a binary search on the file, it seems like a real waste ...

Print possible strings created from a Number

Given a 10 digit Telephone Number, we have to print all possible strings created from that. The mapping of the numbers is the one as exactly on a phone s keypad. i.e. for 1,0-> No Letter for 2->...

Tips for debugging a made-for-linux application on windows?

I m trying to find the source of a bug I have found in an open-source application. I have managed to get a build up and running on my Windows machine, but I m having trouble finding the spot in the ...

Trying to split by two delimiters and it doesn t work - C

I wrote below code to readin line by line from stdin ex. city=Boston;city=New York;city=Chicago and then split each line by ; delimiter and print each record. Then in yet another loop I try to ...

Good, free, easy-to-use C graphics libraries? [closed]

I was wondering if there were any good free graphics libraries for C that are easy to use? It s for plotting 2d and 3d graphs and then saving to a file. It s on a Linux system and there s no gnuplot ...

Encoding, decoding an integer to a char array

Please note that this is not homework and i did search before starting this new thread. I got Store an int in a char array? I was looking for an answer but didn t get any satisfactory answer in the ...

热门标签