进程间通信,产生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 SIGPIPE\n");
exit(1);
}

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

unix c

抽疯似的微笑 12 years, 4 months ago

下面的代码有问题,你在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 .

希兹克利夫 answered 12 years, 4 months ago

Your Answer