2017-12-11 22 views
0

파이프를 통해 bc를 사용하여 char 표현식의 답을 얻으려고합니다. 먼저 pipe1에 식을 쓰고 싶습니다. 그러면 bc가 pipe2에서 응답을 읽고 씁니다. 이를 위해 입출력을 변경하고 있습니다. 때로는파이프와 포크를 통해 bc 사용

(standard_in) 2: illegal character: ^@ 

: 나는 탭을 선언하는 경우

write(pipe1[1], "20*5\n", sizeof("20*5\n")-1) != sizeof("20*5\n")-1) 

는하지만,이 오류가 계속 : 나는 문자 []를 사용하여 바로 쓰기의 표현을 넣어하지 않는 경우이 작동합니까 2 대신 1입니다.

내가 뭘 잘못하고있는거야? 누군가가 나를 설명 할 수 있다면, 고마워.

코드 :

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

    char* expression = "20*5\n"; 

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

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

     if (write(pipe1[1], expression, sizeof(expression)) != sizeof(expression)) 
      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; 
} 
+0

변수'expression'은 포인터가 아니라 배열입니다. 'sizeof' 대신'strlen()'을 사용하십시오. (나는이 질문의 이전 변종에 대한 나의 이전 대답에 대한 해설에서'strlen()'을 사용했다.) –

+0

괜찮아, 제 사과를 받아 들여주세요, 나는 그 순간에 정말로 그것을 얻지 못했습니다. – Karl

+0

사과가 받아 들여짐 - 유용한 정보의 덩어리를 논평의 해독 (답변 내외부) 사이에서 발견하는 것은 어려울 수 있습니다. –

답변

1

^@은 NUL 문자 즉 '\0'입니다. 이 문자열을 bc에 쓸 때 문자열의 끝을 초과한다는 뜻입니다. 문제는 여기에 있습니다 :

sizeof(expression) 

expression

, 그것은 64 비트 컴퓨터에있는 경우, 문자열 "20*5\n"의 첫 번째 문자를 가리키는과 char 포인터 배열이다 아니다, 그 크기는 8.입니다 보낼 문자열의 길이를 가져 오려면 대신 strlen(expression)을 사용하십시오.

문제와 관련이 없으면 부모 프로세스에서 응답을 읽은 후 자식 프로세스가 완료되도록 wait을 수행해야합니다. 그렇지 않으면 좀비가 남을 것입니다.

+0

답변 해 주셔서 감사 드리며 기다려 보겠습니다. – Karl

+0

부모가 자식 프로세스를 빠져 나가기 전에 시스템 프로세스 (일반적으로 PID 1,'init')는 자식 프로세스를 상속 받고 좀비를 생성하지 않는다는 것에주의하십시오. 당신이 좀비를 얻는 유일한 시간은 부모 프로세스가 자식 프로세스가 종료 될 때까지 종료되지 않지만 부모 프로세스가 어떤 단계에서 자식 프로세스를 기다리지 않는 경우입니다.부모가 많은 좀비를 생성하면 이것은 문제가됩니다. 하나의 좀비는 거의 문제가되지 않으며 많은 프로세스가 공정하게 신속하게 종료되므로 원하는 좀비가 시스템에 의해 자동으로 정리됩니다. –

1

이것은 당신은 당신의 시스템이 32 비트의 경우는, char*입니다 expressionsizeof 연산자를 사용하는

if (write(pipe1[1], expression, sizeof(expression)) != sizeof(expression)) 

, 그것은 어떤 포인터 변수의 크기 인 4가 발생합니다

잘못하여 암호.

sizeof 대신 strlen(expression)을 사용해야합니다.

답변에서도 지적했듯이 부모 프로세스에 둘 이상의 하위 프로세스가있는 경우 하위 프로세스가 실행을 마친 후 종료해야합니다. 이상적으로는 반환 값인 wait도 확인해야합니다.이 값은 하위 프로세스가 어떻게 종료되었는지 더 자세히 설명합니다.

+0

좋아요. 이것 역시 시도해 보겠습니다. 도움을 주셔서 감사합니다. 많은 도움이됩니다. – Karl