【发布时间】:2018-12-16 12:02:08
【问题描述】:
我正在进行一项测试,有人问我如何让“读取”睡眠或“写入”停止进程”
对于后者,我不明白为什么我的 sigpipe 确实被提升了,但并没有停止这个过程:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <errno.h>
#define READING 0
#define WRITING 1
#define DESCRIPTOR_COUNT 2
void signal_handler(int signal){
printf("sigpipe received\n");
}
int main(void)
{
int tube[DESCRIPTOR_COUNT];
pipe(tube);
// signal(SIGPIPE, signal_handler);
close(tube[READING]);
if(write(tube[WRITING], "message", 8)<0)
if(errno==EPIPE)
printf("EPIPE returned\n");
printf("123");
return EXIT_SUCCESS;
}
没有 signal()(引用)
使用 signal()(未引用)
SIGPIPE 确实收到了,但如果我不处理它,进程应该停止,但由于我可以写“123”,这意味着进程没有停止。 为什么?
我也在 Fedora 28 上,我正在使用代码块 17.12。
SIGPIPE 是否被忽略...?原因?
解决方案?
struct sigaction action;
action.sa_handler = SIG_DFL;
sigaction(SIGPIPE, &action, 0);
用它替换signal() 将具有预期的默认行为!
编辑我现在已将标题从“SIGPIPE 不停止进程”更改为“为什么更改了默认 SIGPIPE 处理程序?”
================================================ =======
回答
在与来自 codeblocks 的人交谈后,codeblocks 使用 wxWidgets,并且在 linux(此处为 fedora 28)上 wxWidgets 使用 gtk 库,正如 cmets 中的 Mark Plotnick 所解释的,gtk 更改了 SIGPIPE 的信号处理程序,因为 codeblocks 运行代码使用fork 或 exec,通过代码块运行的代码受 gtk 库的影响。
【问题讨论】:
-
嗯,适用于 me,Linux。平台是什么?它适用于这个minimal reproducible example 吗?如果忽略 SIGPIPE,
write将返回EPIPE。是这样吗? -
Fedora 28,epipe 没有返回:/
-
write()==EPIPE ...:: write 出错时返回 -1,并将 errno 设置为 EPIPE。 -
从命令行尝试一下。
-
在 gdb 下运行代码块。原来 gtk 库在几个地方正在使进程忽略 sigpipe。第一个是 github.com/linuxmint/gtk/blob/master/gtk/gtkmain.c#L689 。评论说
Since 2.18, GTK+ calls signal (SIGPIPE, SIG_IGN) during initialization, to ignore SIGPIPE signals, since these are almost never wanted in graphical applications. If you do need to handle SIGPIPE for some reason, reset the handler after gtk_init(), but notice that other libraries (e.g. libdbus or gvfs) might do similar things.可能想向代码块人员提出功能请求。
标签: c pipe signals codeblocks