2017-03-03 105 views
1

我們必須編寫一個C程序,它將使用管道將一個命令/程序的stdin重定向到另一個命令/程序stdout。如果命令行上的程序通過了./a.out ls -l \; more,它應該將ls -l的標準輸出重定向到more,其中\;是分隔符。這個程序應該適用於我們路徑中的任何命令/程序:./a.out cat filename.c \; more,應該與鍵入:cat filename.c | more相同。管道將一個程序的stdout重定向到另一個程序的stdin

我的問題是,我的程序似乎無法正確執行或者管道沒有按預期工作。除了打印語句調試之外,基本上我只得到了輸出。具體來說,程序輸出:Exec ...然後是ERROR,這些都在父代碼中。

#include <fcntl.h> 
    #include <stdio.h> 
    #include <stdlib.h> 
    #include <unistd.h> 
    #include <sys/types.h> 
    #include <sys/wait.h> 
    void pipeit(char * pro1, char * pro2, char * p1args[], char * p2args[]) 
    { 
    pid_t pid; 
    int fd[2]; 
    int st; 
    pipe(fd); 
    pid = fork(); 

    if(pid < 0) 
    { 
     printf("Error Forking...\n"); 
     exit(-1); 
    } 
    else if(pid == 0) 
    { 
     dup2(fd[1],1); 
     close(fd[0]); 
     close(1); 
     printf("Exec 1...\n"); 
     execv(pro1, p1args); 
     printf("ERROR\n"); 
    } 
    else 
    { 
     waitpid(pid,&st,0); 
     if(st<0) 
     { 
      printf("Child Error\n"); 
     } 
     dup2(fd[0],0); 
     close(fd[1]); 
     close(0); 
     printf("Exec...\n"); 
     execv(pro2,p2args); 
     printf("ERROR\n"); 
    } 
    return; 
    } 
    /* THIS IS JUST COMMAND LINE PARSING */ 
    int main(int argc, char * argv[]) 
    { 
    int i = 1; 
    char * pro1; 
    char * pro2; 
    char * first[argc+1]; 
    char * second[argc+1]; 
    while(i<argc && argv[i][0] != ';') 
    { 
     if(i == 1) 
     { 
      pro1 = argv[i]; 
     } 
     else 
     { 
      first[i] = argv[i]; 
     } 
     i++; 
    } 
    first[i] = NULL; 
    while(i<argc) 
    { 
     if(argv[i][0] == ';') 
     { 
      i++; 
      pro2 = argv[i]; 
     } 
     else 
     { 
      second[i] = argv[i]; 
     } 
     i++; 
    } 
    second[i] = NULL; 
    pipeit(pro1,pro2,first, second); 
    return 0; 
    } 

回答

0

在孩子,你有:

dup2(fd[1],1); 
    close(fd[0]); 
    close(1); 

這將複製管到標準輸出,但然後關閉標準輸出。通過不關閉標準輸出並關閉管道的兩端來修復。經驗法則:如果將管道的一端複製到標準輸入,輸出或錯誤,則應關閉兩個原始管道描述符。

dup2(fd[1],1); 
    close(fd[0]); 
    close(fd[1]); 

在標準輸入被關閉的情況下,父母有類似問題。

您也有wait()在錯誤的地方。這些進程必須同時運行。如果管道中的第一個進程產生了太多的數據以至於管道無法保存全部數據,則該進程將被阻止。如果另一個進程在讀取任何內容之前正在等待第一個進程死亡,則它不會運行良好。

相關問題