Back to index

nordugrid-arc-nox  1.1.0~rc6
daemon.cpp
Go to the documentation of this file.
00001 #ifdef HAVE_CONFIG_H
00002 #include <config.h>
00003 #endif
00004 
00005 #include <iostream>
00006 #include <fstream>
00007 
00008 #include <cstdio>
00009 #include <cstdlib>
00010 #include <cstring>
00011 // NOTE: On Solaris errno is not working properly if cerrno is included first
00012 #include <cerrno>
00013 
00014 #include <assert.h>
00015 #include <fcntl.h>
00016 #include <signal.h>
00017 #include <unistd.h>
00018 #include <sys/types.h>
00019 #include <sys/stat.h>
00020 
00021 #ifdef HAVE_SYS_FILE_H
00022 #include <sys/file.h>
00023 #endif /* HAVE_SYS_FILE_H */
00024 
00025 #include "daemon.h"
00026 
00027 namespace Arc {
00028 
00029 Logger Daemon::logger(Logger::rootLogger, "Daemon");
00030 
00031 Daemon::Daemon(const std::string& pid_file, const std::string& log_file_) : pid_file(pid_file)
00032 {
00033     pid_t pid = fork();
00034     switch(pid) {
00035         case -1: // parent fork error
00036             logger.msg(ERROR, "Daemonization fork failed: %s", strerror(errno));
00037             exit(1);
00038         case 0: // child
00039             /* clear inherited umasks */
00040             ::umask(0);
00041             /*
00042              * Become a session leader: setsid must succeed because child is
00043              * guaranteed not to be a process group leader (it belongs to the
00044              * process group of the parent.)
00045              * The goal is not to have a controlling terminal.
00046              * As we now don't have a controlling terminal we will not receive
00047              * tty-related signals - no need to ignore them.
00048              */
00049             setsid();
00050             /* redirect standard input to /dev/null */
00051             if (std::freopen("/dev/null", "r", stdin) == NULL) {
00052                 fclose(stdin);
00053             }
00054             /* forward stdout and stderr to log file */
00055             if (std::freopen(log_file_.c_str(), "a", stdout) == NULL) {
00056                 fclose(stdout);
00057             }
00058             if (std::freopen(log_file_.c_str(), "a", stderr) == NULL) {
00059                 fclose(stderr);
00060             }
00061             break;
00062         default:
00063             /* write pid to pid file */
00064             std::fstream pf(pid_file.c_str(), std::fstream::out);
00065             pf << pid;
00066             pf.close();
00067             /* succesful exit from parent */
00068             _exit(0);
00069     }
00070 }
00071 
00072 Daemon::~Daemon() {
00073     // Remove pid file
00074     unlink(pid_file.c_str());
00075     Daemon::logger.msg(INFO, "Shutdown daemon");
00076 }
00077 
00078 } // namespace Arc