2013-07-18 128 views
2

編輯: 解決的辦法是重定向子進程的標準輸入和stdout到管道

int c1=dup2(pipes[0][1],STDOUT_FILENO); 
int c2=dup2(pipes[1][0],STDIN_FILENO); 


setvbuf(stdout,NULL,_IONBF,0); 

這是setvbuf用來設置標準輸出爲無緩衝。即使我正在打印換行符,如果目標不是實際的屏幕,我想它會變成緩衝區。



編輯: 當我把fflush(標準輸出) LINE 1和fflush(FOUT)後,4號線它按預期工作後。但是,如果沒有在LINE 1之後執行fflush(stdout),問題在於我無法將fflush放入我計劃運行的程序中。


我想從我的過程開始另一個程序。我沒有訪問它的代碼,但我知道它使用stdin和stdout進行用戶交互。我試圖通過創建2個管道來啓動該程序,並將孩子的標準輸入/標準輸出重定向到適當的管道端。要點是,父應該能夠通過文件描述符與孩子通信,而其標準輸入/標準輸出應該是完整的。 POPEN系統調用僅打開單向管道。下面的代碼幾乎可以工作。

有4行標記爲LINE 1..4。

LINE 1是兒童發送給管, LINE 2是孩子從管接收, LINE 3是父發送給管, LINE 4是父從管接收,

這僅僅是一個玩具爲例來確保事情有效。問題是,是LINE1..4未被註釋輸出I在終端上看到的所有4條線是

PARENT1: -1 
FD: 1 0 4 5 0 1 
DEBUG1: 0 
DEBUG2: 0 

雖然如果線1和線3是未註釋僅我看到的連續的數據流。如果只有LINE 2和LINE 4未註釋,則會發生同樣的情況。但是,我想要一個完整的雙向通信。同時添加註釋的SLEEP不會改變行爲。

這裏可能是什麼問題。我想知道爲什麼沒有雙向POPEN。

int pid; 
int pipes[2][2]; 

pipe(pipes[0]); 
pipe(pipes[1]); 

pid=fork(); 

if(pid==0) 
    { 
    //usleep(1000000); 
    close(pipes[0][0]); 
    close(pipes[1][1]); 

    int c1=dup2(pipes[0][1],STDOUT_FILENO); 
    int c2=dup2(pipes[1][0],STDIN_FILENO); 
    //int c2=dup2(STDIN_FILENO,pipes[1][0]); 

    fprintf(stderr,"FD: %d %d %d %d %d %d\n",c1,c2,pipes[0][1],pipes[1][0],STDIN_FILENO,STDOUT_FILENO); 

    //FILE*fout=fdopen(pipes[0][1],"w"); 
    //FILE*fin =fdopen(pipes[1][0],"r"); 
    while(1) 
    { 
    static int c1=0; 
    fprintf(stderr,"DEBUG1: %d\n",c1); 
    printf("%d\n",c1);      // LINE 1 
    fprintf(stderr,"DEBUG2: %d\n",c1); 
    scanf("%d",&c1);      // LINE 2 
    fprintf(stderr,"DEBUG3: %d\n",c1); 
    c1++; 
    } 
    //fclose(fout); 
    //fclose(fin); 
    return 0; 
    } 

close(pipes[0][1]); 
close(pipes[1][0]); 

char buffer[100]; 
FILE*fin=fdopen(pipes[0][0],"r"); 
FILE*fout=fdopen(pipes[1][1],"w"); 
while(1) 
    { 
    int c1=-1; 
    printf("PARENT1: %d\n",c1); 
    fscanf(fin,"%d",&c1);       // LINE 3 
    printf("Recv: %d\n",c1); 

    fprintf(fout,"%d\n",c1+1);     // LINE 4 
    printf("PARENT3: %d\n",c1+1); 
    } 
fclose(fin); 
fclose(fout); 
+0

可以回答你自己的問題!不要用解決方案編輯原始問題,而應該將其作爲答案發布,然後接受它。 –

回答

1

你的代碼是很長,所以我不知道我有明白一切,但你爲什麼不使用select? 你想在一個tird進程中重定向孩子的輸出還是在父進程中使用它?

下面的例子是貓在子進程中。

#include <unistd.h> 
#include <stdlib.h> 

int  main() 
{ 
    pid_t pid; 
    int p[2]; 


    pipe(p); 
    pid = fork(); 
    if (pid == 0) 
    { 
     dup2(p[1], 1); // redirect the output (STDOUT to the pipe) 
     close(p[0]); 
     execlp("cat", "cat", NULL); 
     exit(EXIT_FAILURE); 
    } 
    else 
    { 
     close(p[1]); 
     fd_set rfds; 
     char  buffer[10] = {0}; 

     while (1) 
     { 
      FD_ZERO(&rfds); 
      FD_SET(p[0], &rfds); 
      select(p[0] + 1, &rfds, NULL, NULL, NULL); //wait for changes on p[0] 
      if(FD_ISSET(p[0], &rfds)) 
      { 
       int  ret = 0; 
       while ((ret = read(p[0], buffer, 10)) > 0) //read on the pipe 
       { 
        write(1, buffer, ret); //display the result 
        memset(buffer, 0, 10); 
       } 
      } 
     } 
    } 
} 
+0

其實我找到了解決辦法。 SETVBUF將stdout設置爲非緩衝(即使我正在打印換行符,但目標不是實際的屏幕,我想它會被緩衝。 – user1068779

+0

我這樣做的原因是我啓動的程序有一個PRINT-EVAL循環,我想以編程方式響應。 – user1068779

+0

@ user1068779很高興您找到了解決方案。 您仍然可以在父進程中向p [1]寫入響應 – Alexis

相關問題