Forum Programmation.php Problème entre php (fonction exec) et un daemon perl.

Posté par  .
Étiquettes : aucune
0
4
juil.
2005
Bonjour,

J'ai du pour mon stage développer un outil réseau. Celui-ci, réalisé en perl, se lance comme une daemon grâce à un double fork, à la fermeture des entrées/sorties standards, un changement de Sid qui devraient totalement détacher celui-ci du terminal (enfin je crois ^^).

L'interface d'administration de ce produit a été développée en Php et permet de configurer un certain nombre de choses et , pour simplifier la vie des utilisateurs, de démarrer, arrêter ou redémarrer ce daemon. Pour cela j'utilise la fonction exec (Version de php 4.2.2).

J'ai d'abord cru que tout marchait à merveille. Jusqu'au jour ou j'ai redémarré httpd pendant que mon daemon était en cours d'exécution et qu'httpd n'a pas pu être redémarré parce qu'aussitôt httpd arrêté, mon daemon perl s'était mis à écouter les ports 443 et 80. (Demarrage de httpd : (98)Adresse deja utilisee: make_sock: could not bind to address 0.0.0.0:443
no listening sockets available, shutting down ; Après vérification avec netstat, c'est le pid de mon daemon qui est bindé sur ce port).

Ce qui est étrange :
1) Mon script perl n'effectue aucune connexion mis à part à une base Mysql (avec le module CPAN Mysql) et un serveur mail (avec le module CPAN Net::SMTP). D'ailleurs sans approfondir comment fonctionne ce daemon, il est la plupart du temps en attente d'une nouvelle ligne écrite dans un fichier qu'il surveille (grâce à un open qui pipe l'exécution du tail de ce fichier).
2) Si je fais un sudo de l'argument passé à exec pour démarrer mon daemon, et que j'arrête le service httpd, je peux le redémarrer sans problème. Mon daemon ne va pas parasiter les ports 443 et 80.

J'en déduis donc qu'une ligne de commande passée a la fonction exec ne revient pas exactement au même que de lancer cette même commande avec pour utilisateur apache. Mais je n'ai pas assez de connaissances à ce sujet pour comprendre exactement ce bug. Ai-je mal détaché mon script perl ? Pourquoi le bug n'intervient-il pas quand je fais un sudo -u apache ?

Merci d'avance,
Andonya
  • # Fermeture des fichiers

    Posté par  (site web personnel) . Évalué à 2.

    Quand tu fais un fork, le nouveau process recupere les file descriptor, y compris ceux des socket je pense. Si tu ne les fermes pas dans ton démon, il les garde ouvert.
    sudo doit faire ca proprement et tout fermer avant d'executer ton programme.
    • [^] # Re: Fermeture des fichiers

      Posté par  . Évalué à 1.

      J'ai épuré au maximum le code, en otant la partie "utile". Avec ce peu de code, le bug survient toujours au moment de l'arrêt d'apache...

      Côté php :

      echo "Begin script..";
      exec("perl ./test.pl"); // ai aussi essayé avec passthru et system
      // même probleme...
      echo "After exec...";


      Côté perl :

      #!/usr/bin/perl -w
      use strict;
      use POSIX 'setsid';

      # First fork
      if (!fork)
      {
      # Redirecting input and output to /dev/null
      open STDIN, '/dev/null' or die "Can't read /dev/null: $!";
      open STDOUT, '>/dev/null';
      # Second fork, daemon isn t related anymore to the terminal.
      if (!fork)
      {
      chdir '/'
      or die "Can't chdir to /: $!";
      setsid;
      open STDERR, '>&STDOUT' or die "Can't dup";
      while (my $line = 1)
      {

      }
      }
      exit 0;
      }
      wait;


      J'ai donc fermé les entrées sorties, je n'utilise pas d'autre file descripteur/socket...
      Ca commence à me desespérer, je n'aimerais pas livrer un produit qui peut empêcher apache de redémarerr s'il est lancé au moment de son arrêt....

      Merci d'avance,
      Andonya

Suivre le flux des commentaires

Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.