2012-09-10 68 views
1

我想分叉進程並執行命令。我正在創建一個命名管道,並試圖從將STDOUT寫入管道的子進程執行命令。父進程將從管道讀取。我的問題是父進程沒有完全從管道讀取數據。這裏是代碼。父進程不完全讀取命名管道中的數據

fifo_fd = mkfifo(MY_FIFO, 0666); 
FILE *fp = fdopen(fifo_fd, "r"); 
childpid = fork(); 
if (childpid == 0) 
{ 
    dup2(fifo_fd, STDOUT_FILENO); 
    dup2(fifo_fd, STDERR_FILENO); 
    close(fifo_fd); 
    execv(arg_list[0], arg_list); 
    _exit (127); 
} 
else 
{ 
    //parent process 
    if(waitpid(childpid, &status,WNOHANG) == -1) { 
    // now we kill the child and return failure. 
    } 

    fcntl(fd, F_SETFL, O_NONBLOCK); 

    while((fgets(buf, sizeof(buf)-1,fp))) { 
    strcat(result,buf); //we copy the buf to result 
} 
return success; 
} 
+0

那麼,你的閱讀有一個嚴重的缺陷:在你真正開始閱讀之前,你正在等待孩子死亡。這意味着你依賴於事物來完全適應系統提供的任何緩衝區;除此之外的任何事情都會導致僵局。不管這是否也會導致你所看到的症狀是我不能說的,但是。 –

+0

@ChristianStieber:WNOHANG選項將確保waitpid dosent掛機?我能夠從父進程中的管道讀取,但它完全讀取 – prabhu

回答

0

您希望使用pipe而不是fifo,這樣您就不需要創建文件系統條目。正如@Christian所說,你還需要確保兩個進程併發運行,否則管道/ FIFO可能會阻塞並導致程序掛起。

嘗試如下所示。

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

int main() { 
    int pipe_fd[2]; 
    pipe(pipe_fd); 

    if (fork() == 0) { 
     dup2(pipe_fd[1], STDOUT_FILENO); 
     dup2(pipe_fd[1], STDERR_FILENO); 
     close(pipe_fd[0]); 
     close(pipe_fd[1]); 
     char *arg_list[] = {"/bin/echo", "hello", 0}; 
     execv(arg_list[0], arg_list); 
     __builtin_unreachable(); 

    } else { 
     close(pipe_fd[1]); 
     char buf[32]; 
     int count; 
     for (;;) { 
      count = read(pipe_fd[0], buf, sizeof(buf)); 
      if (count <= 0) break; 
      write(STDOUT_FILENO, buf, count); 
     } 
    } 

    return 0; 
} 
+0

確實阻止read()返回時,像一個函數如alarm(nsecs);火災? – prabhu

+0

是的,'alarm'發送一個信號,所以'read'將返回'EINTR'。 – jleahy

+0

當SIGALRM發送時,程序終止了嗎?當讀取終止於EINTR時,我們該如何處理? – prabhu