使用信号处理程序时打印错误

时间:2013-10-09 02:46:43

标签: c shell signal-handling

在C上编写类似shell的程序时,我遇到了信号处理方面的问题 这是我的代码的简化版本:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
#define SIZE 255

void sig_handler(int sig){
if (sig == SIGINT)
    printf("\n[shell]$\n");
}

int main()
{
    char input[SIZE];
    printf("[shell]$");
    signal(SIGINT,sig_handler);
    while( gets(input) != NULL ){
    // code of the shell including command interpreter and command execution
        printf("[shell]$");
    }
    return 0;
}

当我运行程序并使用命令 - “cat”尝试SIGINT时,输出显示如下:

[shell]$ ^C  (ctrl+C pressed for the first time)
[shell]$     
^C           (the input position go to the next line, which is unwanted)
[shell]$
cat          (I want it in the same line with [shell]$)
^C
[shell]$
[shell]$     (duplicate printing occurs)

我试图通过删除第二个\ n来修改函数void sig_handler(int sig)。然而,情况变得比以前更糟。第一次按ctrl + C时,程序不会自动触发信号事件。

为了澄清我的问题,我要问的两个问题是: 1.如何使用[shell] $?在同一行上输入位置? 2.如何解决重复打印问题?

2 个答案:

答案 0 :(得分:1)

@zneak说的是真的,您可以使用fflush并删除\n中的第二个sig_handler

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
#define SIZE 255

void sig_handler(int sig){
if (sig == SIGINT)
    printf("\n[shell]$");
    fflush(stdout);
}

int main()
{
    char input[SIZE];
    printf("[shell]$");
    fflush(stdout);
    signal(SIGINT,sig_handler);
    while( gets(input) != NULL ){
    // code of the shell including command interpreter and command execution
        printf("[shell]$");
    }
    return 0;
}

答案 1 :(得分:1)

首先,从信号处理程序打印是一个坏主意。信号处理程序就像一个中断处理程序 - 它是异步发生的,它可以在你的标准库代码中引发,并且调用另一个stdlib例程可能会搞乱它的非重入内部(想象一下SIGINT在{在你的循环中{1}}。

如果您真的想从内部输出内容,最好使用原始printf()调用write()文件描述符。