2012-02-16 27 views
3

通過在C 2管我試圖創建一個使用用C在Linux上2管父子進程之間的雙向通信。父母是我的程序,孩子只是一個隨機程序(說「貓」)。雙向親子溝通在Linux上

我嘗試在父母使用read()閱讀孩子的輸出,但它給了我錯誤號9,這是錯誤的文件描述符。

下面是我的代碼

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

#define Read   0 
#define Write   1 
#define ParentRead  read_pipe[1] 
#define ParentWrite  write_pipe[0] 
#define ChildRead  write_pipe[1] 
#define ChildWrite  read_pipe[0] 

int main() 
{ 
    int data_processed; 

    /** Pipe for reading for subprocess */ 
    int read_pipe[2]; 
    /** Pipe for writing to subprocess */ 
    int write_pipe[2]; 

    char buffer[100]; 
    memset(buffer, '\0', 100); 

    if (pipe(read_pipe) == 0 && pipe(write_pipe) == 0) 
    { 
     pid_t pid = fork(); 
     if (pid == (pid_t)-1) 
     { 
      fprintf(stderr, "Fork failure"); 
      exit(EXIT_FAILURE); 
     } 
     else if (pid == (pid_t)0) //Child process 
     { 
      close(Read); 
      close(Write); 
      close(ParentRead); 
      close(ParentWrite); 
      dup(ChildRead); 
      dup(ChildWrite); 
      execlp("cat", (char*)NULL); 
      exit(EXIT_FAILURE); 
     } 
     else { //Parent process 
      close(ChildRead); 
      close(ChildWrite); 

      write(ParentWrite, "abc", 3); 
      int r = read(ParentRead, buffer, 99); 
      printf("%d %d", r, errno); 
      puts(buffer); 
     } 
    } 

    exit(EXIT_SUCCESS); 
} 
+3

open()在執行I/O之前的管道。 – 2012-02-16 20:13:09

+0

不是(pipe(read_pipe)== 0 && pipe(write_pipe)== 0)與打開管道相同嗎? – Jeff 2012-02-16 20:48:14

+0

是的,這是一樣的。 – mikithskegg 2012-02-16 20:54:19

回答

2

如果你想stdin和stdout重定向到管道,你需要使用DUP2(2)系統調用。

dup2 (ChildRead, 0); 
dup2 (ChildWrite, 1); 

P.S. 另外我發現在管道中讀/寫的錯誤方向。這裏是正確的方法

#define ParentRead  read_pipe[0] 
#define ParentWrite  write_pipe[1] 
#define ChildRead  write_pipe[0] 
#define ChildWrite  read_pipe[1] 

記住:pipe [0]是fd讀取,pipe [1]是fd寫入。

還有一錯誤,在execlp。不要忘記將您發送給執行的程序的第一個參數設置爲程序的名稱

execlp("cat", "cat", (char*)NULL); 
+0

我改變了所有DUP()來DUP2(),但仍得到相同的結果。 read()返回-1與errno 9. – Jeff 2012-02-16 21:09:01

+0

我發現了一個更多的錯誤,我在答案中描述。 – mikithskegg 2012-02-16 21:20:12

+0

我怎麼會這麼粗心。當我編寫程序時,我甚至會加倍檢查。我現在沒有收到錯誤,但是read()返回0 – Jeff 2012-02-16 21:34:50

0

,如果你只是進行讀/寫,會發生什麼?我不能確定的是DUP和貓是你想要的這裏,說實話:

char buf[256]; 
int len; 

len = read(ChildRead, 256); 
write(ChildWrite, len); 

,並進一步思考,如果你知道你想結束了,使用DUP2的FD,不DUP。知道你的API,人!

而且,想更進一步,你可以看看源器一起(3)調用,它正是這樣做的,更普遍的方式。

+1

我以貓爲例。我有另一個我想要調用的子程序。另外popen()不允許雙向通信。 – Jeff 2012-02-16 20:50:48

+0

Socketpair()允許雙向通信。 – wildplasser 2012-02-16 23:49:19

+0

@Jeff:POPEN不* *正是這一點,你只需要把它擴展到兩個管道,而不是一個 – tbert 2012-02-17 07:04:01