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);
    }