2010-11-22 32 views
0

Je veux savoir quand mon processus fils est en cours de fermeture. Mais je ne veux pas bloquer mon application, alors j'utilise WNOHANG.Mauvais statut lors de l'utilisation de waitpid avec WHOHANG

#include <sys/types.h> 
#include <sys/wait.h> 
#include <signal.h> 
#include <unistd.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 

void handler(int nsig) { 
    int status; 
    waitpid(-1, &status, WNOHANG); 
    printf("nsig=%i; status=%i\n", nsig, status); 
    if (WIFEXITED(status)) { 
    printf("Exited\n"); 
    } 
} 

int main() { 
    struct sigaction act; 
    act.sa_handler = handler; 
    if (sigaction(SIGCHLD, &act, 0) < 0) { 
    fprintf(stderr, "sigaction failed\n"); 
    exit(-1); 
    } 

    pid_t fpid; 
    fpid = fork(); 
    if (fpid == 0) { 
    execlp("okular", "okular", 0); 
    } 
    while(1); 
    return 0; 
} 

Cela fonctionne très bien si je ferme "okular" comme d'habitude.

$ ./test 
nsig=17; status=0 
Exited 

Mais si je fais quelque chose comme

kill -STOP OKULAR_PID 

J'ai la même sortie et ce qui ne va pas pour moi, parce que Okular n'a pas quitté en fait.

+0

Ce n'est pas votre problème, mais vous devez savoir que l'appel 'printf' d'un gestionnaire de signal entraîne généralement un comportement indéfini. –

+0

Merci pour l'avertissement. – Ximik

Répondre

1

Je pense que c'est correct, parce que SIGCHLD est défini comme étant terminé ou arrêté par un enfant, comme on peut le voir dans ce man page pour le signal. SIGCLD est un synonyme de SIGCHLD.

+0

Mais alors pourquoi WIFEXITED fonctionne? – Ximik

+3

@Ximik: Vous ne devez inspecter 'status' que si waitpid()' a renvoyé une valeur '> 0'. – caf

+0

Merci. C'est la solution. – Ximik