質問

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