2014-04-26 2 views
0

다음 C 프로그램이 실행되고 SIGUSR1이 실행중인 프로세스로 반복적으로 전송되면 pclose() 호출이 13을 반환하는 경우가 있습니다. 13은 내 시스템에서 SIGPIPE에 해당합니다.pclose()가 간헐적으로 SIGPIPE를 반환합니다.

왜 이런 일이 발생합니까?

while true; do kill -SIGUSR1 <process-id>; done을 사용하여 SIGUSR1을 프로그램에 보내고 있습니다. 이 프로그램은 Ubuntu 14.04에서 실행됩니다.

#include <pthread.h> 
#include <signal.h> 
#include <unistd.h> 
#include <stdio.h> 

void handler(int i) {} 

void* task(void*) 
{ 
    FILE *s; 
    char b [BUFSIZ]; 
    while (1) { 
     if ((s = popen("echo hello", "r")) == NULL) { 
      printf("popen() failed\n"); 
     } 
     while (fgets(b, BUFSIZ, s) != NULL) ; 
     if (int r = pclose(s)) { 
      printf("pclose() failed (%d)\n", r); 
     } 
    } 

    return 0; 
} 

int main(int argc, char **argv) 
{ 
    struct sigaction action; 
    action.sa_handler = handler; 
    sigemptyset(&action.sa_mask); 
    action.sa_flags = 0; 
    sigaction(SIGUSR1, &action, NULL); 

    pthread_t tid; 
    pthread_create(&tid, 0, task, NULL); 
    pthread_join(tid, NULL); 
} 

답변

2

이것은 fgets이 신호에 의해 중단되면 발생합니다. 프로그램이 끝까지 파이프를 읽지 않고 닫습니다. 그런 다음 다른 프로그램이 SIGPIPE합니다.

올바른 파이프 읽기 작업은 다음과 같습니다

do { 
    while (fgets(b, BUFSIZ, s) != NULL) ; 
} while (errno == EINTR); 
+0

감사합니다. 나는 fgets() 문서를 다음과 같이 더 가깝게 읽어야한다. "성공적으로 완료되면 fgets()는 s를 리턴해야한다. 스트림이 파일의 끝 부분에 있다면, 스트림의 파일 끝 표시자가 설정되고 fgets()는 널 포인터를 리턴해야한다. ** 읽기 오류가 발생하면, 스트림에 대한 오류 지시자가 설정되고, fgets()는 널 포인터를 리턴하고 오류를 나타내도록 errno를 설정해야한다. ** " –