2009-11-16 6 views

Répondre

50

Selon Programmation avancée de Stevens dans l'environnement UNIX chapitre 13, c'est la procédure pour faire un démon Unix bien comportés:

  1. fourche et ont la sortie de parent. Cela fait que le shell ou le script de démarrage pense que la commande est terminée. En outre, le processus fils est garanti de ne pas être un chef de groupe de processus (une condition préalable pour setsid suivant)
  2. Appelez setsid pour créer une nouvelle session. Cela fait trois choses:
    1. Le processus devient un chef de file de la session d'une nouvelle session
    2. Le processus devient le leader du groupe de processus d'un nouveau groupe de processus
    3. Le procédé n'a pas de contrôle terminal de
  3. Optionnellement bifurquer à nouveau et faire sortir le parent. Ce guarantes que le démon n'est pas un chef de session et ne peut pas acquérir un terminal de contrôle (sous SVR4)
  4. Modifier le répertoire de travail courant / pour ne pas interférer avec le montage et le démontage
  5. Set masque de création de fichier en mode 000 pour permettre création de fichiers avec toute autorisation requise ultérieurement.
  6. Fermez les descripteurs de fichiers inutiles hérités du parent (il n'existe aucun terminal de contrôle): stdout, stderr et stdin.

De nos jours, il existe un fichier pour suivre le PID qui est largement utilisé par les scripts de démarrage de distribution Linux. Assurez-vous d'écrire le PID du petit-enfant, soit la valeur de retour de la seconde fourche (étape 3) ou la valeur de getpid() après l'étape 3.

Voici une implémentation Ruby, principalement traduit du livre, mais avec la double-fourchette et l'écriture du démon PID.

# Example double-forking Unix daemon initializer. 

raise 'Must run as root' if Process.euid != 0 

raise 'First fork failed' if (pid = fork) == -1 
exit unless pid.nil? 

Process.setsid 
raise 'Second fork failed' if (pid = fork) == -1 
exit unless pid.nil? 
puts "Daemon pid: #{Process.pid}" # Or save it somewhere, etc. 

Dir.chdir '/' 
File.umask 0000 

STDIN.reopen '/dev/null' 
STDOUT.reopen '/dev/null', 'a' 
STDERR.reopen STDOUT 
+4

Ou utilisez http://daemons.rubyforge.org – ephemient

+0

C'est vraiment une excellente explication! Merci beaucoup d'avoir répondu à votre propre question. Pas tout le monde le fait même s'ils ont trouvé une solution à ce problème plus tard. – t6d

+0

De rien! Je suis heureux de contribuer. – JasonSmith

Questions connexes