2013-02-25 98 views
4

我不确定是否可以完成以下任务,因为我无法通过Google找到任何问题/结果。我想将fork()的stdout更改为管道,然后将其更改回正常的stdout。Unix C - 将stdout重定向到pipe然后返回stdout

这是我有:

FirstExecutable:

int main() 
{ 
     int fd[2]; //Used for pipe 
     int processID; 

     if(pipe(fd) == -1) 
     { 
      printf("Error - Pipe error.\n"); 
      exit(EXIT_FAILURE); 
     } 

     if((processID = fork()) == -1) 
     { 
      fprintf(stderr, "fork failure"); 
      exit(EXIT_FAILURE); 
     } 

     if(processID == 0) 
     { 
      int newFD = dup(STDOUT_FILENO); 

      char newFileDescriptor[2]; 

      sprintf(newFileDescriptor, "%d", newFD); 

      dup2 (fd[1], STDOUT_FILENO); 

      close(fd[0]); 

      execl("./helloworld", "helloworld", newFileDescriptor, NULL); 
     } 
     else 
     { 
      close(fd[1]); 

      char c[10]; 

      int r = read(fd[0],c, sizeof(char) * 10); 

      if(r > 0) 
       printf("PIPE INPUT = %s", c); 
     } 
} 

的HelloWorld

int main(int argc, char **argv) 
{ 
     int oldFD = atoi(argv[1]); 

     printf("hello\n"); //This should go to pipe 

     dup2(oldFD, STDOUT_FILENO); 

     printf("world\n"); //This should go to stdout 
} 

所需的输出:

world 
PIPE OUTPUT = hello 

实际输出:

hello 
world 
+1

'man perror'不要使用'fprintf'打印错误信息而不用'strerror' – 2013-02-25 06:33:53

+0

感谢您的提示! – MrHappyAsthma 2013-02-25 07:56:00

回答

3

尝试改变

printf("hello\n"); 

printf("hello\n"); 
    fflush(stdout); 

这里的问题是缓冲。出于效率原因,FILE句柄在写入时不会总是立即生成输出。相反,他们将文本累积在内部缓冲区中。

有三种缓冲模式,无缓冲,行缓冲和块缓冲。无缓冲的句柄总是立即写入(stderr未缓冲)。行缓冲句柄等待,直到缓冲区已满或打印一个换行符('\n')(如果指向终端,则标准输出为行缓冲)。块缓冲手柄等待,直到缓冲区满(标准输出是块缓冲,如果它没有引用终端)。

当你的helloworld程序启动时,stdout进入一个管道,而不是终端,所以它被设置为块缓冲。因此printf调用只是将文本存储在内存中。由于缓冲区没有满,只有在标准输出关闭时才会刷新缓冲区,在这种情况下,程序退出时会发生这种情况。

但是,在程序退出时,文件描述符1(stdout)已被恢复,以引用父级的原始stdout,而不是管道。因此缓冲输出最终被写入原始stdout。

fflush强制将缓冲的文本立即写入。

+0

工作就像一个魅力! fflush()究竟做了什么,它为什么解决我的问题?如果你不介意我问!另外,我会再次接受这6分钟。 – MrHappyAsthma 2013-02-25 03:52:08