2017-12-09 7 views
1

배관 및 포크를 사용하여 C에서 작동하도록 노력하고 있습니다. "10 + 10 같은 조작"| bc파이프 2 개, 포크 1 개, Bc 및 execlp (C)

정확하게 말해서, 서버가 작업을 작성하고 bc가 읽히는 곳과 작업의 결과 (bc가 사용되는 곳)가 가서 서버가 그것을 읽고 printf 그것. 이를 위해 부모 프로세스와 하위 프로세스의 출력과 입력을 변경하려고합니다.

INT 주() {

int t1, t2; 
char resultat[5]; 
int pipe1[2]; 
int pipe2[2]; 

pipe(pipe1); 
pipe(pipe2); 


int resultat_fork = fork(); 

if(resultat_fork == -1){ 
    exit(EXIT_FAILURE); 
} 

if(resultat_fork!=0){ 
    printf("I am the parent\n"); 

    close(pipe1[0]); 
    close(pipe2[1]); 
    //We only want to write into pipe1 and read from pipe2, we can close the two other 

    write(pipe1[1], "20*5\n", 20); 
    //write on pipe1 the expression 

    read(pipe2[0], resultat, sizeof(resultat)); 
    //read from pipe2 the answer (written by bc) 

    printf("resultat : %s\n",resultat); 

    close(pipe1[1]); 
    close(pipe2[0]); 


}else{ 
    printf("I am the children\n"); 

    close(pipe1[1]); 
    close(pipe2[0]); 
    //We only want to write into pipe2 and read from pipe1, we can close the two other 

    dup2(pipe1[0], 0); 
    //redirection standard input to pipe1[0] 

    dup2(pipe2[1], 1); 
    //redirection standard output to pipe2[1] 

    execlp("bc", "bc", NULL); 
    //execute bc, which normaly will read the operation from pipe1 and write the answer into pipe2, but I think it's here the problem come out 

    close(pipe1[0]); 
    close(pipe2[1]); 
} 


return 0; 

}

나는 있지만 오류와 정답을 받고 있어요 : "(standard_in)이 여기에

내 코드입니다 : 잘못된 문자 :^@ " "(표준 입력) 2 : 잘못된 문자 : : " 플러스 CTRL C를 눌러 종료해야합니다. BC에서 온 것 같지만 이유는 ...

내가 뭘 잘못하고 있니? 고맙습니다! 나는 예를 거의 보지 못했지만 파이프 하나만 던졌습니다.

+0

귀하의 시험 부모/자식이 잘못되었습니다. 'fork()'가 0을 반환하면, 당신은 자식이다. 그렇지 않은 경우 반환되는 값은 본질적으로 값 1이 아닌 자식의 PID입니다. –

+0

"나는 여기 있습니다"라는 메시지가 인쇄 되었다면 "나는 유치하고 있습니다"라는 두 프로세스를 보았을 것입니다. 그리고 나는 "나는 부모가된다"고 말하지도 않았다. –

+0

답변 해 주셔서 감사합니다. 참으로 수치 스럽다. 나는 이것을 정말로 유감스럽게 생각한다. 지금 그것은 나를 계속 돌려 보낸다. "(standard_in) 1 : 불법적 인 문자 :^@".나는 그것이 제대로 사용되지 않는 dup2에서 온다고 믿지만, 확실하지 않다. – Karl

답변

1

이것은 작동합니다. 그것이 쓰여지는 데이터의 크기, 쓰기와 읽기를 검사하는 방법, 파일 기술자를 닫는 방법을 지정하는 방법에 유의하십시오. (주의 사항 : sizeof("string literal") 카운트 널 바이트를, strlen() 달리 또한 컴파일 시간 상수이다 그러나, 일반적인 목적의 코드는 현재 표현 문자열에 strlen()을 사용합니다...) 엄지 손가락의

규칙 :을 당신이 dup2()를 사용하는 경우 파이프 파일 기술자를 표준 입력 또는 표준 출력으로 복제하십시오. 모두 파이프 끝을 닫으십시오.

dup() 또는 fcntl()F_DUPFD 또는 F_DUPFD_CLOEXEC으로 사용하는 경우에도 해당됩니다.

#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 

int main(void) 
{ 
    char resultat[5]; 
    int pipe1[2]; 
    int pipe2[2]; 

    pipe(pipe1); 
    pipe(pipe2); 

    int resultat_fork = fork(); 

    if (resultat_fork == -1) 
    { 
     exit(EXIT_FAILURE); 
    } 

    if (resultat_fork != 0) 
    { 
     printf("I am the parent\n"); 

     close(pipe1[0]); 
     close(pipe2[1]); 

     if (write(pipe1[1], "20*5\n", sizeof("20*5\n") - 1) != sizeof("20*5\n") - 1) 
      fprintf(stderr, "write to child failed\n"); 

     int nbytes = read(pipe2[0], resultat, sizeof(resultat)); 
     if (nbytes <= 0) 
      fprintf(stderr, "read from child failed\n"); 
     else 
      printf("resultat: [%.*s]\n", nbytes, resultat); 

     close(pipe1[1]); 
     close(pipe2[0]); 
    } 
    else 
    { 
     printf("I am the child\n"); 

     close(pipe1[1]); 
     close(pipe2[0]); 
     dup2(pipe1[0], 0); 
     dup2(pipe2[1], 1); 
     close(pipe1[0]); /* More closes! */ 
     close(pipe2[1]); /* More closes! */ 

     execlp("bc", "bc", NULL); 
     fprintf(stderr, "Failed to execute bc\n"); 
     exit(EXIT_FAILURE); 
    } 

    return 0; 
} 

오류 처리를 개선 할 여지가 여전히 있습니다. 코드는 일부 오류를보고 한 후 계속 실행됩니다. 이는 아마도 최상의 동작이 아닙니다.

출력 :

I am the parent 
I am the child 
resultat: [100 
] 

(참고 :.. 당신이 파이프 어딘가에 프로그램의 출력, 당신은 I am the child 메시지가 표시되지 않는 경우 그 이유를 들어 왜 printf() anomaly after fork() 참조)

+0

고맙습니다. 지금 당장은 코드를 테스트 할 수 없지만 가능한 한 빨리 시도하고 답해 드리겠습니다. – Karl