문제

When the following C program is executed, and SIGUSR1 is sent to the running process repeatedly, the pclose() call will sometimes return 13. 13 corresponds to SIGPIPE on my system.

Why does this happen?

I am using while true; do kill -SIGUSR1 <process-id>; done to send SIGUSR1 to the program. The program is executed on 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);
}
도움이 되었습니까?

해결책

This happens when fgets gets interrupted by the signal. The program doesn't read the pipe to the end and closes it. The other program then SIGPIPEs.

The correct pipe reading operation is:

 do {
    while (fgets(b, BUFSIZ, s) != NULL) ;
 } while (errno == EINTR);
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top