【问题标题】:Wrong printing when using signal handler使用信号处理程序时打印错误
【发布时间】:2013-10-09 02:46:42
【问题描述】:

我在用 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. 如何解决重复打印问题?

【问题讨论】:

  • 不确定重复的东西,但是您可以通过删除打印字符串末尾的 \n 来使内容打印在同一行(尽管您可能需要使用 fflush(stdout) 来制作它出现)。
  • 非常感谢!对于重复的问题,我通过创建另一个没有 printf 的信号处理函数来解决它。

标签: c shell signal-handling


【解决方案1】:

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

#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;
}

【讨论】:

  • 非常感谢!我的程序现在可以按我的意愿运行了。
【解决方案2】:

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

如果你真的想从内部输出一些东西,你最好使用原始的write() 调用stderr 文件描述符。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多