Programmation de démons

Description

Déjà, pour ceux qui ne le sauraient pas, un démon à unix ce que les services sont à windows : un programme tournant en arrière-plan, le plus souvent invisibles à l'utilisateur.

J'ai réalisé celui-ci à partir de documentations anglaises trouvées sur google, mais je n'ai pas repris un des exemples expliquant comment s'interfacer avec syslogd pour gérer les logs, il suffit d'un man syslogd pour avoir assez de détails :)

Enfin, comme j'avais pas vu de sources sur ce sujet, je place celle-ci en espérant que çà serve à d'autres...

Source / Exemple :


#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <sys/stat.h>

void quitter(int signal) {
  /* libérer ici toute la mémoire allouée par le démon */
  remove("toto.pid"); /* supprimer le fichier contenant le PID */
  exit(EXIT_SUCCESS); /* fin du démon */
}

void executer(void) {
  FILE* f; /* ce fichier contiendra le PID du démon */
  f = fopen("toto.pid", "rt");
  if (f != NULL) { /* le fichier PID existe : une instance est déjà en mémoire */
    fclose(f);
    fprintf(stderr, "le démon est déjà en mémoire (ou a mal été terminé)\n");
    exit(EXIT_FAILURE);
  }
  f = fopen("toto.pid", "wt");
  if (f == NULL) { /* impossible d'écrire le fichier PID */
    fprintf(stderr, "impossible d'écrire le fichier toto.pid\n");
    exit(EXIT_FAILURE);
  }
  fprintf(f, "%i", getpid()); /* on écrit le PID du démon dans le fichier (ex: httpd.pid) */
  fclose(f); /* on ferme le fichier, dont on a plus besoin */
  while (1) {
    sleep(1); /* remplacer le sleep par le code du démon, return pour quitter proprement */
  }
}

int main(void) { /* pas besoin des arguments pour cet exemple ;-) */
  switch (fork()) { /* duplication */
  case -1: /* échec de la duplication */
    fprintf(stderr, "erreur avec fork\n");
    return EXIT_FAILURE;
  case 0: /* duplication réussie : côté fils */
    if (setsid() == -1) { /* on tente de créer un nouveau groupe pour notre démon */
      fprintf(stderr, "erreur avec setsid\n");
      return EXIT_FAILURE;
    }
    if (signal(SIGTERM, quitter) == SIG_ERR) { /* on enregistre les signaux auquels le démon doit répondre */
      fprintf(stderr, "erreur avec signal\n");
      return EXIT_FAILURE;
    }
    chdir("/tmp/"); /* aller dans le répertoire de travail du démon */
    umask(066); /* on modifie les permissions des fichiers créés par le démon en rw------- */
    executer(); /* entrée dans la boucle principale du démon */
    quitter(SIGTERM); /* quitter le démon proprement */
  default: /* duplication réussie : côté père */
    return EXIT_SUCCESS;
  }
}

Conclusion :


Le zip contient toto.c et Makefile. Vous pouvez :
- make clean = nettoyer les fichiers binaires
- make compile = compiler le démon (make tout court marche aussi)
- make run = exécute le démon
- make kill = terminer le démon

Pour vérifier le chargement du démon s'il n'y a pas eu d'erreurs au lancement, faites un ps -x, le démon devrait sommeiller quelque part dans la liste... Et le fichier toto.pid devrait contenir le PID correspondant au démon chargé !

Pas de bug connu, hormis la gestion un peu simpliste des instances.

Codes Sources

A voir également

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.