【发布时间】:2012-10-28 18:06:11
【问题描述】:
我编写了检测 SIGINT 的控制台程序,所以当用户按下 Ctrl+C 时,程序会执行一些操作并终止。
但是当我用管道将此程序重定向到任何其他程序时,例如:
./my_program | tee xxx
SIGINT 永远不会出现在我的处理程序中。尽管这个程序终止。
处理 SIGTERM 没有任何效果。 SIGTERM 也不会出现在 Ctrl+C 之后。
如何检测到程序在所有情况下都被 Ctrl+c 中止?
我的 SIGINT 和 SIGPIPE 测试用例:
#include <csignal>
#include <cstdio>
bool break_request=false;
bool term_request=false;
extern "C" void break_handler(int)
{
break_request=true;
printf("Ctrl+C detected\n");
}
extern "C" void term_handler(int)
{
term_request=true;
printf("pipe detected\n");
}
int main()
{
signal(SIGINT,break_handler);
signal(SIGPIPE,term_handler);
while(true)
{
if(break_request)
{
printf("break request handled\n");
break;
}
if(term_request)
{
printf("pipe request handled\n");
break;
}
}
printf("terminating\n");
}
【问题讨论】:
-
嗯,Ctrl-C 只会发出最后一个程序的信号,即
tee。充其量,my_program会得到一个 SIGPIPE,因为管道的读取端已关闭。 -
如果我没记错的话,如果管道另一边的程序死了,你可能会得到
SIGPIPE。尝试将其设置为SIG_IGN或以相同方式处理。 -
传统上,中断将被发送到管道中的所有程序。我不确定信号应该去向的定义是否/何时发生了变化,但是我遇到了一些简单的脚本在我想要它们时没有死的问题——这既令人惊讶又(非常)烦人。我使用的是
ksh而不是bash;我还没有计算出这个因素有多大。