Вопрос

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