2013-07-09 2 views
2

나는 fork와 execvp를 통해 명령을 실행하는 다음과 같은 기능을 가지고있다. 포크에서 시작한 내 스크립트는 입력 데이터를 듣고 있습니다. 어떻게 데이터를 myscript로 보낼 수 있습니까?파이프 포크에 쓰는 방법은 무엇입니까?

int external_command() 
{ 

    int pfds[2]; 
    if (pipe(pfds) < 0) 
     return -1; 

    if ((uproc.pid = fork()) == -1) 
     return -1; 

    if (uproc.pid == 0) { 
     /* child */ 

     const char *argv[4]; 
     int i = 0; 
     argv[i++] = "/bin/sh"; 
     argv[i++] = "myscript.sh"; 
     argv[i++] = NULL; 

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

     execvp(argv[0], (char **) argv); 
     exit(ESRCH); 

    } else if (uproc.pid < 0) 
     return -1; 

    /* parent */ 
    close(pfds[1]); 

    int status; 
    while (wait(&status) != uproc.pid) { 
     DD("waiting for child to exit"); 
    } 

    char buffer[64]; 
    ssize_t rxed; 
    char *c; 
    int t; 

    //read from fork pipe 
    *value = NULL; 
    while ((rxed = read(pfds[0], buffer, sizeof(buffer))) > 0) { 
     if (*value) 
      t = asprintf(&c, "%s%.*s", *value, (int) rxed, buffer); 
     else 
      t = asprintf(&c, "%.*s", (int) rxed, buffer); 

     if (t == -1) return -1; 

     free(*value); 
     *value = strdup(c); 
     free(c); 
    } 
    // how to write to the pipe fork? 
} 
+0

'fork'가 음수 * 2 회 *로 반환되는지 확인합니다. –

+0

파일 설명자 duping이 나에게 의심스러워 보입니다. – trojanfoe

+0

코드'} else if (uproc.pid <0)가 -1을 반환하면'else '는 전혀 필요치 않습니다. 당신은 이미 그 사건을 다루었습니다. –

답변

2

파이프가 단방향입니다. pipe을 두 번 호출하여 자식에서 데이터를 읽는 파일 설명자 한 쌍을 얻고 (다른 사용자는 이미 가지고있는 것처럼) 자식에게 보낸 데이터를 새로 작성합니다. 새 파이프를 자식의 stdin으로 설정하려면 이미 수행중인 것과 동일한 종류의 dup2close 마술을 수행해야합니다.

+0

내 코드를 편집 할 수 있습니까? – MOHAMED

+0

그래서'int pfds [3];'을 정의해야합니다. 그리고 자식에서 :'dup2 (pfds [2], 0); 닫기 (pfds [2])'. 그리고 부모 클래스에서'pfds [0]'을 써서 호출합니다. 맞아? – MOHAMED

2

부모 프로세스에서 자식 프로세스 stdin을 쓰고 싶습니까? 이를 위해 두 개의 파이프를 개 생성해야합니다. 하나는 자식에서 stdout으로 사용되며 다른 하나는 stdin과 동일하게 사용됩니다 (색인이 반대로되어 있음).

물론 아이들은 쓰기 전에 아이들을 위해서 wait을 쓸 수 없습니다. 왜냐하면 자식이 입력을 계속해야한다면 교착 상태가 발생할 수 있기 때문입니다. 파이프의

+0

그래서'int pfds [3];'을 정의해야합니다. 그리고 자식에서 :'dup2 (pfds [2], 0); 닫기 (pfds [2])'. 그리고 부모 클래스에서'pfds [0]'을 써서 호출합니다. 맞아? – MOHAMED

+0

@MOHAMED 아니요. 다른 파이프 세트를 만들기 위해'pipe'를 다시 호출하고, 자식에서'otherpfds [0]'을'FILENO_STDIN'으로 사용하십시오. –

0

기본

당신이이 경우에 부모 프로세스 (아버지)

int fd[2]; /*write(fd[1],buffer,strlen) 
      /read(fd[0],buffer2,SIZE)*/ 
pid_t cpid; 

if(pipe(fd)==-1){ 
    perror("pipe"); 
    exit(EXIT_FAILURE); 
} 
if((cpid=fork())<0){/* FORK INIT */ 
    printf("\n\tFORK ERROR\n"); 
    exit(1); 
} 
if(cpid==0){   /*SON*/ 
    close(fd[0]); 
    /********CODE******/ 
    if((write(fd[1],final2,strlen(final2)))<0){ 
     perror("\n\tWRITE ERROR"); 
    } 
    close(fd[1]); 
}else{     /*FATHER*/ 
    close(fd[1]); 
    if((read(fd[0],aler,NN))<0){ 
     perror("\n\tREAD ERROR"); 
    } 
    wait(NULL); 
    /********CODE******/ 
    close(fd[0]); 
} 

을하고 무엇을 배울 수 있도록 새 (아들) (정보를 읽는 코드의이 비트를 연구하십시오) 과정

원하는 경우

양방향 읽기() 쓰기()이 파이프 (FD1 [2], FD2 [2])

를 만들 라이트 엔드 FD1을 닫고 아버지 판독 상기와 동일한 논리를 사용하는 단계 [1], 아들

아버지 기록 다른 방향 [0]

반대로 판독 단부 FD1을 닫고 쓴다 상기를 닫고 읽기 끝 fd2 [0], 아들 읽기, 쓰기 끝내기 fd2 [1]

관련 문제