/* ================================================================================ RPL/2 (R) version 4.1.31 Copyright (C) 1989-2019 Dr. BERTRAND Joël This file is part of RPL/2. RPL/2 is free software; you can redistribute it and/or modify it under the terms of the CeCILL V2 License as published by the french CEA, CNRS and INRIA. RPL/2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the CeCILL V2 License for more details. You should have received a copy of the CeCILL License along with RPL/2. If not, write to info@cecill.info. ================================================================================ */ #include "rpl-conv.h" /* ================================================================================ Fonction de bascule vers un mode de fonctionnement de daemon ================================================================================ Entrées : pointeur sur une structure -------------------------------------------------------------------------------- Sorties : -------------------------------------------------------------------------------- Effets de bord : néant ================================================================================ */ void lancement_daemon(struct_processus *s_etat_processus) { pid_t pid; pid_t sid; /* * Si le processus en cours est déjà un daemon (dont le père est init), * on ne fait rien. */ if (getppid() == (pid_t) 1) { return; } /* * Premier fork pour lancer un setsid(). Le fork() n'est pas protégé par * un mutex car on ne peut transformer en daemon que le processus de * lancement du RPL/2. */ fflush(NULL); pid = fork(); if (pid < 0) { (*s_etat_processus).erreur_systeme = d_es_processus; return; } if (pid > 0) { // Fin du processus père. // À noter : dans le cas où l'on utilise l'émulation des // sémaphores anonymes POSIX ou la sémantique SysV, il faut // détruire les sémaphores et les recréer dans le processus fils. # ifndef SEMAPHORES_NOMMES sem_post(&((*s_etat_processus).semaphore_fork)); sem_destroy(&((*s_etat_processus).semaphore_fork)); # else sem_post((*s_etat_processus).semaphore_fork); sem_destroy3((*s_etat_processus).semaphore_fork, getpid(), pthread_self(), SEM_FORK); # endif destruction_queue_signaux(s_etat_processus); _exit(EXIT_SUCCESS); } sid = setsid(); if (sid < 0) { (*s_etat_processus).erreur_systeme = d_es_processus; return; } if ((chdir((*s_etat_processus).chemin_fichiers_temporaires)) < 0) { (*s_etat_processus).erreur_systeme = d_es_processus; return; } # pragma GCC diagnostic push # pragma GCC diagnostic ignored "-Wunused-result" freopen("/dev/null", "r", stdin); freopen("/dev/null", "w", stdout); freopen("/dev/null", "w", stderr); # pragma GCC diagnostic pop /* * Second fork pour ne plus être un session leader. */ fflush(NULL); pid = fork(); if (pid < 0) { (*s_etat_processus).erreur_systeme = d_es_processus; return; } if (pid > 0) { // Fin du processus père. _exit(EXIT_SUCCESS); } (*s_etat_processus).pid_processus_pere = getpid(); liberation_queue_signaux(s_etat_processus); creation_queue_signaux(s_etat_processus); modification_pid_thread_pere(s_etat_processus); return; } // vim: ts=4