C-进程间通信,产生SIGPIPE 信号的原因及处理方式
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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
下面的代码有问题,你在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
.初始化时候修改为
/*
* 为了防止进程退出,设置忽略信号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