eponyme's blog : linux, dev & cie

Placer un timeout sur l'exécution d'une fonction en C / C++

Il peut être intéressant en programmation de pouvoir contrôler le temps maximum d'exécution d'une fonction, pour par exemple éviter un blocage de l'application à cause d'un bug, ou d'une boucle infinie car la condition de sortie n'arrive jamais. Il existe plusieurs mécanismes pour y arriver, notamment l'utilisation de SIGALRM, les conditions des pthreads, ou encore les sémaphores. C'est cette dernière solution, que je trouve plus simple, que j'ai retenue pour gérer les timeouts des fonctions de mon robot IRC trustyRC, m'assurant ainsi qu'il ne se gèlera pas si un plugin chargé se bloquait. Je la présente ici, au travers d'un exemple simple.

Un serveur TCP en C, sans fork, ni threads

Il est très courant, voir systématique, dans les tutos décrivant le fonctionnement d'un serveur TCP écrit en C, de voir l'utilisation de la fonction fork() pour gérer le dialogue avec un client connecté. Des raisons bien connues font que fork() est souvent délaissé au profit d'un thread dédié à cette tâche. Sauf que la encore, ca n'est pas forcément la solution idéale. Tout d'avord, l'éternel souci du partage des ressources, mais aussi les attentions particulières qu'ils faut avoir si on arrête le serveur (et donc les processus fils), pour le relancer ensuite (dans le programme lui même, et non pas en stoppant/relançant le programme). Je propose ici une méthode différente.

Comparer deux masques en C++

Il est facile en C/C++ de savoir si une chaine correspond à un masque, surtout si celui-ci ne contient que des étoiles. On peut même d'ailleurs utiliser la fonction "fnmatch()". En revanche, comment comparer deux masques, c'est à dire savoir s'ils recouvrent le même type de chaîne ? Par exemple, eponyme*toto correspond il avec *toto  (utile pour comparer un masque de user IRC par rapport à un masque de ban) ? Le problème semblait difficile, et c'est "bigbourin" qui en quelques dizaines de minutes à pondu le code :

int masksMatch(char*str1,char*str2)
{  if (*str1 == 0 && *str2 == 0)
    return (1);
  if (*str1 == '*')
    {
      if (*str2 == 0)
      return (masksMatch(str1 + 1, str2));
      else
      return (masksMatch(str1 + 1, str2) || masksMatch(str1, str2 + 1));
    }
  if (*str2 == '*')
    {
      if (*str1 == 0)
      return (masksMatch(str1, str2 + 1));
      else
      return (masksMatch(str1 + 1, str2) || masksMatch(str1, str2 + 1));
    }
  if (*str1 == *str2)
    return (masksMatch(str1 + 1, str2 + 1));
  return (0);
}

La fonction renverra '1' si le masque str1 correspond au masque str2.

Bravo et merci à 'bigbourin'.

Fabien