2012-08-07 2 views
2

이것은 더 큰 프로그램의 일부분이지만 execvp의 출력을 얻으려는 것입니다. execvp를 정확하게 지시 한 dup2으로 설정했습니다 파이프에. 파이프의 전체 길이를 읽으려면 read를 사용할 때 내 문제가 발생합니다. execvp의 출력이 입력에 따라 다를 수 있으므로 얼마나 큰지는 알 수 없습니다.당신의 수신 출력이 execvp에서 수신 할 때 파이프에서 올바른 양의 데이터를 읽음

int fd[2]; 
    pipe(fd); 
    pid_t pid = fork(); 
    if (pid == 0) { 
     close(fd[0]); 
     dup2(fd[1], 1); 
     execvp(msg.v,(char *[]){msg.v,NULL}); 
    } else if (pid > 0) { 
     close(fd[1]); 
     read(fd[0],msg.v,....); 
    } 

나는 그 중 하나 충분하지 않은 몇 가지 다른 읽기 크기지만을 시도하거나 난 당신이는 popen 사용할 수 있습니다 알고 끝과 다른 몇 가지 표준 입출력에서 일하지만에서 임의의 쓰레기를 치울의 할당에 필요한 우리는 출력을 얻으려는 다른 방법을 비우는 Im을 사용하지 않습니다.

조금 더 쓸모없는 정보는 전체 프로그램이 서버의 일부입니다. 나는 서버와 클라이언트를 만들고있다. 서버를 시작하면 클라이언트에게 INET 스트림을 통해 서버로 보내고 stdio없이 출력을 모두 출력하기 위해 출력을 클라이언트로 보낸다.

답변

1

read이 버퍼로 얼마나 많은 양의 데이터를 반환하는지주의해야합니다. read은 양수를 반환하지만 더 많은 데이터가 있습니다. 프로그램이 완료되면 pipe의 끝을 닫고 read0을 반환합니다.

} else if (pid > 0) { 
    close(fd[1]); 
    ssize_t r = read(fd[0],buf,bufsz); 
    if (r > 0) do { 
     /* ... do something with r bytes in buf */ 
     r = read(fd[0],buf,bufsz); 
    } while (r > 0); 
    if (r < 0) { 
     perror("read"); 
     /*...*/ 
    } 
} 

당신이 read를 참조하면

는 당신이 언급 한 카페 EINTR 경우가 발생 한에 "중단 된 시스템 호출"오류를 제공합니다. 이 경우 다시 read을 다시 시작하십시오.

 for (;;) { 
      r = read(fd[0],buf,bufsz); 
      if (r != -1 || errno != EINTR) break; 
     } 

난 당신이 "일시적으로 사용할 수없는 자원"메시지를 비 블록 I/O, 그래서 당신은 발생하지 않습니다를 수행하지 않는 가정입니다.

+0

나는 이것을 언급하지는 않았지만 루프를 통과 할 수있는 stdio를 사용하여 sprintf를 사용하여 내 메시지를 함께 보내 주셔서 감사합니다! – Mintybacon

+0

@Mintybacon : 대단히 환영합니다. 문안 인사 – jxh

1

당신은 EOF를 표시 read() 반환 0까지 계속 읽고 (-1 EAGAIN 또는 EINTR 이외는 영구적 인 오류로 errno 세트로).

반환 값 read()을 무시하면 안됩니다. 반환 된 바이트 수를 알려줍니다. 따라서 버퍼 끝에 "쓰레기"가 표시되는 것입니다.이 경우에는 read()이 전체 버퍼를 채우지 않아 반환 값을 무시하므로 실제로 반환 된 값을 알 수 없습니다.