Frage

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);
}
War es hilfreich?

Lösung

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);
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top