2014-04-16 63 views
1

我需要使用叉爲我的操作系統類實現無名管道,但我不能讓它工作。它是一個簡單的代碼,沒有什麼特別的,但我什麼也沒有得到。我試圖運行 ls -l | wc -l,但我每次都得到0。使用叉子和管道實現管道

#include <stdio.h> 
#include <dirent.h> 
#include <sys/stat.h> 
#include <sys/types.h> 
#include <fcntl.h> // for open flags 
#include <time.h> // for time measurement 
#include <assert.h> 
#include <errno.h> 
#include <string.h> 

int pid,status; 
int pipefd[2]; 

void my_exec(char* cmd, char** argv) 
{ 
    pipe(pipefd);  // Fixed 
    pid = fork(); 
    // pipe(pipefd); // Original 

    if(pid==0){ 
     close(pipefd[0]); 
     dup2(pipefd[1],fileno(stdout)); 
     close(pipefd[1]); 
     execvp(cmd, argv); 


    } 
    else { 
     close(pipefd[1]); 
     dup2(pipefd[0],fileno(stdin)); 
     while(wait(&status)!=-1); 
     close(pipefd[0]); 
     return; 
    } 

} 

int main(int argc, char** argv) 
{ 
    assert(strcmp(argv[argc-1], "-")); 

    int i; 
    for (i = 1; i < argc; ++i) { 
     if (!strcmp(argv[i], "-")) { 
      argv[i] = NULL; 
      my_exec(argv[1], &argv[1]); 
      argv = &argv[i]; 
      argc -= i; 
      i = 0; 
     } 

    } 

    char* args[argc]; 
    args[argc-1] = NULL; 
    for (i = 1; i < argc; ++i) { 
     args[i-1] = argv[i]; 

    } 

    if (execvp(args[0], args) == -1) 
     perror("execvp failed"); 
    return; 
} 

BTW該命令我試着輸入是ls -l命令 - WC -l(而不是|類型 - )

OK鴨解決了這個問題:我的叉子,更新前,應創建管道。

+2

你不是「實施管道」。您正在使用管道和分叉來創建管道。也許這是語義上的爭吵,但「用叉子實現管道」是一個非常奇怪的表達。 –

+2

初學者在'fork'之前創建管道。 – Duck

+1

備註:如果小孩被阻塞,因爲等待孩子終止寫入管道太多,將無法工作。 –

回答

0

您最大的問題是您在管道前有叉子。這將有效地讓分支的每個分支調用pipe(),因此您將最終得到兩個不同的pipefd集合,而不是相同的集合。反轉fork()和pipe()的調用順序,然後你在每個fork中的文件描述符將是相同的。

作爲一個附註,您可以在if()語句組件中對printf()進行調試,以確保您總共看不到兩個以上的描述符編號。