2010-02-03 4 views
9
#include<stdio.h> 
#include<unistd.h> 
#include<stdlib.h> 

int main(int argc,char **argv) 
{ 
    int fd[2]; 
    pid_t childpid; 
    pipe(fd); 
    childpid=fork(); 
    if (childpid == -1) 
    { 
     perror("Error forking..."); 
     exit(1); 
    } 
    if (childpid) /*parent proces*/ //grep .c 
    { 
     wait(&childpid);  //waits till the child send output to pipe 
     close(fd[1]); 
     close(0);  //stdin closed 
     dup2(fd[0],0); 
     execlp(argv[2],argv[2],argv[3],NULL); 

    } 
    if (childpid==0) //ls 
    { 
     close(fd[0]); /*Closes read side of pipe*/ 
     close(1);  //STDOUT closed 
     dup2(fd[1],1); 
     execl(argv[1],NULL); 
    } 
    return 0; 
} 

"ls grep .c"로 명령 줄 인수를 지정하면 모든 ".c"파일이 표시됩니다.C를 사용하여 파이핑 ("|") 구현 (포크 사용)

의사 코드 : - 자식 프로세스가 그 아이가 파이프에 쓰기 때문에 완료까지 내 자식 프로세스가 실행됩니다 "LS는"& 부모 프로세스가 "그렙이 .c"를 실행합니다 .. 부모 프로세스가 기다립니다.

테스트 실행 : - 왜 무슨 일이 일어나고 있음을

bash-3.1$ ls | grep .c 
1.c 
hello.c 
bash-3.1$ ./a.out ls grep .c 
bash-3.1$ 

?

+0

확인. 나 스스로 대답을 얻었다. $ PATH 환경 변수를 사용하여 파일 이름을 검색하지 않는 자식 프로세스에서 "execl()"을 사용했습니다 ... execlp()로 변경하면 프로그램이 예상대로 실행됩니다. –

+2

아마 "wait (& childpid);도 원하지 않을 것입니다." (또는 그 부정확 한 코멘트)를 거기에 넣는다. 자식으로부터 데이터가 도착할 때까지 기다리지 않고 자식 프로세스 상태가 변경 될 때까지 기다립니다. 출구. 자식 프로세스가 파이프의 데이터 양 (8k) 이상을 쓴다면 부모 프로세스가 종료되기를 기다리는 동안 부모 프로세스가 읽기를 기다리는 동안 응답하지 않습니다. – jmb

+0

그래서, 실제로 실행해야 자식이 실행 된 후에 부모가 실행됩니다 ...? –

답변

8

간단한 실수 : execl 전화는 실제로 execlp이어야합니다. 게다가 waitclose 진술을 제거 할 수 있습니다. 그런 다음 오류 코드 execlp을 확인해야합니다.

+0

+ 답장을 올릴 때 +1 ~ OP가 자신의 답변을 받기 전에 ~ 1 시간이 걸릴 때 – jschmier

+0

exec의 리턴 상태를 테스트 할 필요가 없습니다. *()'함수; 함수가 반환되면 실패합니다. 하지만 오류가있는'exec *()'함수에 대해 어떤 종류의 오류 처리가 있어야한다는 것이 맞습니다. –

1

한 가지 더, close(0)close(1)은 필요하지 않습니다. dup2() 함수가 자동으로이 작업을 수행합니다.

+0

네 말이 맞아. 'close (0)'과'close (1)'은 코드가'dup2()'대신'dup()'을 사용했다면 관련이있다. –