daemonize.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (C), 2000-2003 by Contributors to the monit codebase. 
00003  * All Rights Reserved.
00004  *
00005  * This program is free software; you can redistribute it and/or
00006  * modify it under the terms of the GNU General Public License as
00007  * published by the Free Software Foundation; either version 2 of the
00008  * License, or (at your option) any later version.
00009  *
00010  * This program is distributed in the hope that it will be useful, but
00011  * WITHOUT ANY WARRANTY; without even the implied warranty of
00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013  * General Public License for more details.
00014  * 
00015  * You should have received a copy of the GNU General Public License
00016  * along with this program; if not, write to the Free Software Foundation,
00017  * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
00018  */
00019 
00020 
00021 #include <config.h>
00022 
00023 #include <stdio.h>
00024 #include <stdlib.h>
00025 #include <errno.h>
00026 #include <signal.h>
00027 
00028 #ifdef HAVE_UNISTD_H
00029 #include <unistd.h>
00030 #endif
00031 
00032 #ifdef HAVE_SYS_TYPES_H
00033 #include <sys/types.h>
00034 #endif
00035 
00036 #ifdef HAVE_SYS_STAT_H
00037 #include <sys/stat.h>
00038 #endif
00039 
00040 #ifdef HAVE_FCNTL_H
00041 #include <fcntl.h>
00042 #endif
00043 
00044 #ifdef HAVE_STRING_H
00045 #include <string.h>
00046 #endif
00047 
00048 #include "monitor.h"
00049 
00050 
00063 /* ------------------------------------------------------------------ Public */
00064 
00065 
00070 void  daemonize() {
00071 
00072   pid_t pid;
00073   
00074   /*
00075    * Clear file creation mask
00076    */
00077   umask(0);
00078 
00079   /*
00080    * Become a session leader to lose our controlling terminal
00081    */
00082   if((pid= fork ()) < 0) {
00083     
00084     log("Cannot fork of a new process\n");  
00085     exit (1);
00086     
00087   }  
00088   else if(pid != 0) {
00089     
00090     _exit(0);
00091     
00092   }
00093   
00094   setsid();
00095 
00096   if((pid= fork ()) < 0) {
00097     
00098     log("Cannot fork of a new process\n");  
00099     exit (1);
00100     
00101   }  
00102   else if(pid != 0) {
00103     
00104     _exit(0);
00105     
00106   }
00107 
00108   
00109   /*
00110    * Change current directory to the root so that other file systems
00111    * can be unmounted while we're running
00112    */
00113   if(chdir("/") < 0) {
00114     
00115     log("Cannot chdir to / -- %s\n", STRERROR);
00116     exit(1);
00117     
00118   }
00119 
00120   /*
00121    * Attach standard descriptors to /dev/null. Other descriptors
00122    * should be closed in env.c
00123    */
00124   redirect_stdfd();
00125 
00126 } 
00127 
00128 
00134 int kill_daemon(int sig) {
00135   
00136   pid_t pid;
00137 
00138   if ( (pid= exist_daemon()) > 0 ) {
00139     
00140     if ( kill(pid, sig) < 0 ) {
00141       
00142       error("%s: Cannot send signal to daemon process -- %s\n",prog, STRERROR);
00143       return FALSE;
00144       
00145     }
00146     
00147   } else {
00148     
00149     error("%s: No daemon process found\n", prog);
00150     return TRUE;
00151     
00152   }
00153   
00154   if(sig == SIGTERM) {
00155       
00156     fprintf(stdout, "%s daemon with pid [%d] killed\n", prog, (int)pid);
00157     fflush(stdout);
00158 
00159   }
00160   
00161   return TRUE;
00162   
00163 }
00164 
00165 
00170 int exist_daemon() {
00171 
00172   pid_t pid;
00173   int kill_return= 0;
00174 
00175   errno= 0;
00176 
00177   if((pid= get_pid(Run.pidfile))) {
00178 
00179     if((kill_return= getpgid(pid)) > 0 || errno == EPERM)
00180 
00181       return ( (int)pid ) ;
00182 
00183   }
00184   
00185   return FALSE;
00186 
00187 }
00188