Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/66.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 一旦信号被处理,如何停止从键盘读取?_C_Linux_Signals_Fgets - Fatal编程技术网

C 一旦信号被处理,如何停止从键盘读取?

C 一旦信号被处理,如何停止从键盘读取?,c,linux,signals,fgets,C,Linux,Signals,Fgets,我正在编写一个程序,其中SIGINT信号在第一次发送时进行处理,但在发送之后设置为默认值。例如,我有一个: static volatile int stop_terminating = 1; void handler(int dummy) { stop_terminating = 0; } int main(){ signal(SIGINT, handler); char input[256]; while(1){ if(stop_termin

我正在编写一个程序,其中SIGINT信号在第一次发送时进行处理,但在发送之后设置为默认值。例如,我有一个:

static volatile int stop_terminating = 1;

void handler(int dummy) {
    stop_terminating = 0;
}

int main(){
    signal(SIGINT, handler);
    char input[256];
    while(1){
        if(stop_terminating == 0){
            // reset the action of the signal to default
            signal(SIGINT, SIG_DFL);
            printf("Message sent.\n");
            // increment counter so it doesn't enter this condition again
            stop_terminating++;
        }
        printf("User input:\n");
        fgets(input, sizeof(input), stdin);
        // In this stage, I wanna press CTRL+C and print a message, stopping the fgets
        // but what happens is: I press CTRL+C, the signal is catched, but fgets
        // is still asking for an input, and after I send something, the my message is printed
        // because it looped through the while(1) again.
    }
}

如何阻止fgets请求输入,然后打印消息,然后再次请求输入?

当fgets到达EOF时,您将从fgets获得空值。从键盘上看,通常用CTRL-D(Linux/Unix/MacOS X)或CTRL-Z(DOS/Windows,我认为MacOS在X之前)

Linux信号手册页面上说

信号处理程序中断系统调用和库函数

如果在系统调用或库函数调用被阻止时调用信号处理程序,则:

  • 信号处理程序返回后,调用自动重启;或

  • 调用失败,出现错误
    EINTR

发生这两种行为中的哪一种取决于接口以及是否使用
SA_RESTART
标志建立了信号处理程序(请参见
sigaction
(2))

您可以将
siginterrupt()
函数与
signal()
一起使用,也可以使用
sigaction()
而不是
signal()
来注册信号处理程序,以禁用在收到信号后重新启动
read()
系统调用


但是请注意,在找到换行符之前,C库中的
fgets()
可能多次调用
read()
,因此您可能还需要切换到使用较低级别的函数,而不是
stdio.h
API。

volatile
对于多线程编程来说是不够的。用原子学,我真的不知道怎么做。我一直在努力达到这一点,我知道一些事情只是部分。@Olaf:信号不是线程<代码>易失性就足够了。@BenVoigt:我想知道为什么会有带有额外保证的
sig\u atomic\u t
。有趣的是,这种类型在C11的原子支持之前就已经存在了。注意:
volatile
不保证原子访问。这无助于信号处理,这是问题的关键。CTRL+D实际上不是信号,因此在这种情况下对我没有帮助。但我已经解决了,谢谢你。