C-进程间通信,产生SIGPIPE 信号的原因及处理方式

发布于 2017-01-19 09:17:03 字数 2177 浏览 1312 评论 2

apue书上的一个例子,运行到33行时出现sigpipe信号(书上讲如果写一个读端已关闭的管道,则产生信号SIGPIPE),无法继续运行,不知道怎么解决?谢谢大家指点

 #include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
#include <string.h>

#define MAXLINE 2048

static void err_sys(char *);
static void sig_pipe(int);

int main(void)
{
int n,fd1[2],fd2[2];
pid_t pid;
char line[MAXLINE];

if(signal(SIGPIPE,sig_pipe) ==SIG_ERR)
err_sys("signal error");
if(pipe(fd1) < 0 || pipe(fd2) < 0)
err_sys("pipe error");

if((pid=fork()) < 0)
err_sys("fork error");
else if(pid > 0) //parent
{
close(fd1[0]);
close(fd2[1]);

while(fgets(line,MAXLINE,stdin) !=NULL)
{
n=strlen(line);
if(write(fd1[1],line,n) !=n) /*运行到此处时> 出现SIGPIPE信号,无法继续进行了*/
err_sys("write error");
if((n=read(fd2[0],line,MAXLINE)) < 0)
err_sys("read error");
if(n ==0)
err_sys("child closed pipe");

line[n]=0;
if(fputs(line,stdout) ==EOF)
err_sys("fputs error");
}
if(ferror(stdin))
err_sys("fgets error");
exit(0);
}
else //child
{
close(fd1[1]);
close(fd2[0]);
if(fd1[0] !=STDIN_FILENO)
{
if(dup2(fd1[0],STDIN_FILENO) !=STDIN_FILENO)
err_sys("dup2 error");
close(fd1[0]);
}
if(fd2[1] !=STDOUT_FILENO)
{
if(dup2(fd2[1],STDOUT_FILENO))
err_sys("dup2 error");
close(fd2[1]);
}
if(execl("./myuclc","myuclc",(char *)0) < 0)
err_sys("execl error");
}

exit(0);
}

static void sig_pipe(int signo)
{
printf("caught SIGPIPEn");
exit(1);
}

static void err_sys(char * msg)
{
printf("%sn",msg);
exit(1);
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

甜柠檬 2017-09-02 01:26:39

下面的代码有问题,你在dup2成功的时候却把fd2[1]给关闭了

if(fd2[1] !=STDOUT_FILENO)
{
if(dup2(fd2[1],STDOUT_FILENO))
err_sys("dup2 error");
close(fd2[1]);
}

if(dup2(fd2[1],STDOUT_FILENO))应该改为if(dup2(fd2[1],STDOUT_FILENO))!=STDOUT_FILENO.

归属感 2017-01-22 16:25:41

初始化时候修改为

  /*
* 为了防止进程退出,设置忽略信号SIGPIPE。
*/
signal(SIGPIPE, SIG_IGN);

那么write失败的时候,错误号errno会置为EPIPE,进程就不会退出了
fd is connected to a pipe or socket whose reading end is closed. When this happens the writing process will also receive a SIGPIPE signal. (Thus, the write return value is seen only if the program catches, blocks or ignores this signal.)

http://linux.die.net/man/2/write

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文