2014-04-26 2 views
0

Lorsque le programme C suivant est exécuté, et SIGUSR1 est envoyé au processus en cours d'exécution à plusieurs reprises, l'appel pclose() renvoie parfois 13. 13 correspond à SIGPIPE sur mon système.pclose() renvoie SIGPIPE par intermittence

Pourquoi cela se produit-il? J'utilise while true; do kill -SIGUSR1 <process-id>; done pour envoyer SIGUSR1 au programme. Le programme est exécuté sur 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); 
} 

Répondre

2

Cela se produit lorsque fgets est interrompu par le signal. Le programme ne lit pas le tuyau jusqu'à la fin et le ferme. L'autre programme puis SIGPIPE.

l'opération de lecture de la conduite correcte est:

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

Merci. J'aurais dû lire la documentation 'fgets()' de plus près: "Après avoir réussi, fgets() retournera s Si le flux est en fin de fichier, l'indicateur de fin de fichier pour le flux doit être défini et fgets() doit renvoyer un pointeur NULL. ** Si une erreur de lecture se produit, l'indicateur d'erreur du flux doit être défini, fgets() doit renvoyer un pointeur NULL et doit définir errno pour indiquer l'erreur. ** " –

Questions connexes