IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Réseau C Discussion :

cleaning process fils avec waitpid() fork exec pselect


Sujet :

Réseau C

  1. #1
    Futur Membre du Club
    Homme Profil pro
    Administrateur systèmes et réseaux
    Inscrit en
    Mai 2014
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Administrateur systèmes et réseaux

    Informations forums :
    Inscription : Mai 2014
    Messages : 4
    Points : 7
    Points
    7
    Par défaut cleaning process fils avec waitpid() fork exec pselect
    Hello,

    J'ai un server qui reçoit des messages dans un socket et pour chaque message lance un fork exec. Cette partie fonctionne correctement.
    J'ai ensuite fait la même chose en mode non bloquant en creant une fonction qui gère le nettoyage des process fils terminés avec waitpid().
    Le probleme est que dès que je rajoute la fonction handler qui nettoie les process fils avec waitpid(), alors le waitpid() genère un Interrupted system call à la fonction pselect() avec le message suivant :
    "select(): Interrupted system call"
    J'ai essayé de corriger ceci avec sigprocmask() ( trouvée dans divers forums ) pour bloquer certains signaux, mais sans succés.
    Après plusieurs jours de recherche, je ne parviens pas à corriger.
    Je suis sûr qu'il s'agit d'un problème classique, si vous pouviez éclairer ma lanterne, je vous en serait reconnaissant.
    Merci par avance.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
     
        void clean_up_child_process (int signal_number)
        {
          int status;
          while(waitpid (-1, &status, WNOHANG));
          child_exit_status = status;
        }
     
        static void app(void)
        {
           SOCKET sock;
           char commande[BUF_SIZE];
           char res_cmd[BUF_SIZE];
           int max;
           int n;
     
           sock = init_connection();
           max = sock;
           fd_set rdfs;
     
           sigemptyset(&sigmask);
           sigaddset(&sigmask, SIGCHLD);
           sigaddset(&sigmask, SIGINT);
           sigaddset(&sigmask, SIGTSTP);
           sigaddset(&sigmask, SIGTERM);
           sigprocmask(SIG_BLOCK, &sigmask, NULL);
     
        struct sigaction sigchld_action;
        memset (&sigchld_action, 0, sizeof (sigchld_action));
        sigchld_action.sa_handler = &clean_up_child_process;
        sigaction (SIGCHLD, &sigchld_action, NULL);
     
           while(1)
           {
              int i = 0;
              FD_ZERO(&rdfs);
     
              /* add STDIN_FILENO */
              FD_SET(STDIN_FILENO, &rdfs);
     
              /* add the connection socket */
              FD_SET(sock, &rdfs);
     
        sigemptyset(&empty_mask);
        if (pselect (max + 1, &rdfs, NULL, NULL, NULL, &empty_mask) == -1)
        {
        perror("select()");
        exit(errno);
        }
              if(FD_ISSET(STDIN_FILENO, &rdfs))
              {
                 /* stop process when type on keyboard */
                 break;
              }
              else if(FD_ISSET(sock, &rdfs))
              {
                 /* new client */
                 SOCKADDR_IN csin = { 0 };
                 size_t sinsize = sizeof csin;
                 int csock = accept(sock, (SOCKADDR *)&csin, &sinsize);
                 if(csock == SOCKET_ERROR)
                 {
                    perror("accept()");
                    continue;
                 }
     
                 if((n = recv(csock, commande, BUF_SIZE - 1, 0)) < 0)
                 {
                    perror("recv(commande)");
                    n = 0;
                    continue;
                 }
                 commande[n]=0;
                if ((n=fork())==-1)
                        perror ("fork()");
                else
                if (n==0) 
                {
                        close (STDOUT_FILENO);
                        dup (csock);
                        close (STDERR_FILENO);
                        dup (csock);
                        execlp (commande,commande,0);
                }
                else 
                {
                         closesocket (csock);
                }
              }
           }
           end_connection(sock);
        }

  2. #2
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 369
    Points : 23 623
    Points
    23 623
    Par défaut
    Bonjour et bienvenue,

    Ce n'est pas le waitpid() qui interrompt ton appel système (ici pselect()) mais le signal qui t'a conduit là, donc SIGCHLD. Le masquer t'empêcherait, temporairement en tout cas, d'être prévenu de la mort d'un processus fils. Puisque tu n'utilises pas de subtilités comme la valeur de timeout dans ton appel, tu peux vérifier la valeur de errno, exploitée par perror(), pour identifier la cause de son échec. Si c'est EINTR, tu sauras que c'est un signal qui a interrompu ton appel et tu pourras l'embarquer dans une boucle while pour pouvoir le relancer proprement s'il y a lieu de le faire.

  3. #3
    Futur Membre du Club
    Homme Profil pro
    Administrateur systèmes et réseaux
    Inscrit en
    Mai 2014
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Administrateur systèmes et réseaux

    Informations forums :
    Inscription : Mai 2014
    Messages : 4
    Points : 7
    Points
    7
    Par défaut
    Hello,
    En effet j'ai rajouté quelques tests sur les causes d'erreur possibles et cela fonctionne beaucoup mieux maintenant.
    Merci.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. process defunct avec fork et exec
    Par nabbo dans le forum Programmation et administration système
    Réponses: 5
    Dernier message: 13/09/2013, 15h41
  2. Connaitre PID d'un process lancé avec exec()
    Par hugo123 dans le forum Langage
    Réponses: 4
    Dernier message: 02/06/2006, 14h28
  3. Le process fils doit mourir a la mort du pere!!
    Par dudur001 dans le forum Langage
    Réponses: 4
    Dernier message: 09/11/2005, 09h02
  4. [Swing] execution avec Runtime.getRuntime().exec
    Par benssj5 dans le forum AWT/Swing
    Réponses: 9
    Dernier message: 25/08/2004, 14h54

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo