2013-07-13 2 views
5

나는 C로 내 셸을위한 다중 파이프를 구현하려고한다.C에서 다중 파이프 코딩

내가 가진 파이프 함수는 모두 파이프이다. b가 아니라 a | b | 기음.

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]; 

가 어떻게이 코드를 만들 것입니다 작은 무언가를 추가 할 수있는 여러 파이프하시기 바랍니다 관리 :

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; 

그리고이 두 번째 버전은 무엇입니까? 미리 감사드립니다.

+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); 
} 

을 그런 다음 탭을 통해 실행하고 모든

를 시작합니다 기능
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 내 컴퓨터와 이데온에서도 잘 작동하기 때문에 전화 해주세요. 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; 
} 

a | b | c의 경우 힌트는 p1 [2]와 p2 [2]라는 두 개의 파이프를 사용하는 것입니다. 이것을 시험해보고 어떻게 작동하는지 알려주십시오.