2013-07-13 106 views
5

我正在嘗試在C中實現一個多層管道的外殼。C編碼多個管道

我只有一個管道功能, b但不是| b | C。

int c[2]; 
int returnv; 
pid_t id; 

pipe(c); 
pid = fork()) == 0 
if (pid) 
{ 
    dup2(c[1], 0); 
    close(p[1]); 
    close(p[1]); 
    execvp(array(0), array); 
} 

if ((pid = fork()) == 0) 
{ 
    dup2(p[0], 1); 
    close(p(0)); 
    close(p[0]); 
    returnv = execvp(array[0], array); 
} 

close(p[1]); 
wait(NULL); 
wait(NULL); 
wait(NULL); 
return returnv; 

這是第二個版本:

int i = 0; 

while (i < x) 

{ 
pipe(c); 
if ((pid = fork()) == 0) 
{ 
    dup2(t[i], 1); 
    if (i < 2) 
     dup2(p[0], 1); 
    close(p[1]); 
r= execvp(cmd[i][0], cmd[i]); 
} 
    wait(NULL); 
    close(p[0]); 
    i += 1; 
    t[i] = p[1]; 

我如何添加這個小東西,這將使該代碼管理多個管好嗎? 非常感謝!

+0

其實你只需要調用fork()兩次,而你只需要一次。這是因爲fork()返回兩次:子進程爲0,父進程爲> 1(通常是子進程的pid)。 我不認爲你需要所有的代碼來做你需要的。 – none

+0

我已經花了這麼多時間在這一個,這是唯一的作品^^我想只有一個調用execvp所需的多管道,但我不能讓它的工作。 :( – user2145240

+0

不要從帖子中刪除代碼,它使答案無效 – FDinoff

回答

8

編輯:根據您的評論

要執行你需要存儲你的所有命令的地方倍數管道。 這就是爲什麼我使用結構選項卡。

檢查這個新版本,也許更容易理解

所以首先你需要一個標籤或東西來存儲你的所有命令:

int main() 
{ 
    char *ls[] = {"ls", NULL}; 
    char *grep[] = {"grep", "pipe", NULL}; 
    char *wc[] = {"wc", NULL}; 
    char **cmd[] = {ls, grep, wc, NULL}; 

    loop_pipe(cmd); 
    return (0); 
} 

誰就會通過Tab運行並啓動一切

功能
void loop_pipe(char ***cmd) 
{ 
    int p[2]; 
    pid_t pid; 
    int fd_in = 0; 

    while (*cmd != NULL) 
    { 
     pipe(p); 
     if ((pid = fork()) == -1) 
     { 
      exit(EXIT_FAILURE); 
     } 
     else if (pid == 0) 
     { 
      dup2(fd_in, 0); //change the input according to the old one 
      if (*(cmd + 1) != NULL) 
      dup2(p[1], 1); 
      close(p[0]); 
      execvp((*cmd)[0], *cmd); 
      exit(EXIT_FAILURE); 
     } 
     else 
     { 
      wait(NULL); 
      close(p[1]); 
      fd_in = p[0]; //save the input for the next command 
      cmd++; 
     } 
    } 
} 
+2

@ user2145240我改變了我的答案,舊的有點混亂,因爲我用它來做很多其他的事情;) – Alexis

+1

@ user2145240你能告訴我你是怎麼做的因爲我在我的電腦上工作得很好,而且在ideone上工作也很好http://ideone.com/80e3nd – Alexis

+1

@ user2145240很少有事情要檢查:printf(「9 - On rentre ici?」);請不要忘記\ n在最後, 在exec下添加一個perror,以確保你沒有在env – Alexis

0

我將給出兩種管道模型的工作版本和三種管道模型的提示。試試看看它是否有效。注意:如果你沒有包含正確的頭文件,dup2()將是一場噩夢。

#include <stdio.h> 
#include <unistd.h> 
#include <fcntl.h> 
#include <sys/types.h> 
#include <sys/stat.h> 

int p[2]; 
int pid; 
int r; 

main() 
{ 
    char *ls_args[] = {"ls", NULL}; 
    char *grep_args[] = {"grep", "pipe", NULL}; 

    pipe(p); 

    pid = fork(); 
    if (pid != 0) { 
      // Parent: Output is to child via pipe[1] 

      // Change stdout to pipe[1] 
      dup2(p[1], 1); 
      close(p[0]); 

      r = execvp("ls", ls_args); 
    } else { 
      // Child: Input is from pipe[0] and output is via stdout. 
      dup2(p[0], 0); 
      close(p[1]); 

      r = execvp("grep", grep_args); 
      close(p[0]); 
    } 

    return r; 
} 

對於| b | c,提示是使用兩個管道,即p1 [2]和p2 [2]。試試這個,讓我們知道它是如何工作的。