libmoost
/home/mhx/git/github/libmoost/include/moost/process/detail/daemon_linux.hpp
Go to the documentation of this file.
00001 /* vim:set ts=3 sw=3 sts=3 et: */
00028 #ifndef MOOST_PROCESS_DETAIL_DAEMON_LINUX_HPP__
00029 #define MOOST_PROCESS_DETAIL_DAEMON_LINUX_HPP__
00030 
00031 #include <cstdio>
00032 #include <cassert>
00033 #include <stdexcept>
00034 #include <sys/stat.h>
00035 
00036 #include <boost/function.hpp>
00037 
00038 namespace moost { namespace process {
00039 
00040 class daemon_impl
00041 {
00042 private:
00043    friend class daemon;
00044 
00045    daemon_impl() : pid_(-1) {}
00046 
00052    void fork_(boost::function0<bool> child_init_func)
00053    {
00054        // Our process and Session IDs
00055         pid_t sid;
00056 
00057         // Fork off the parent process
00058         pid_ = fork();
00059         if (pid_ < 0) {
00060            throw std::runtime_error("Unable to fork process");
00061         }
00062 
00063         // The child process must make itself daemon friendly
00064         if (0 == pid_)
00065         {
00066            // Perform child initialisation, if false finalisation of daemon is required.
00067            if(!child_init_func())
00068            {
00069               // Create a new SID for the child process
00070               sid = setsid();
00071               if (sid < 0) {
00072                    throw std::runtime_error("Unable to setsid for child process");
00073               }
00074 
00075               // Change the current working directory
00076               if ((chdir("/")) < 0) {
00077                  throw std::runtime_error("Unable to set current working directory to '/' for child process");
00078               }
00079 
00080               // Redirect standard file descriptors
00081               if (!freopen("/dev/null", "w", stdout))
00082               {
00083                  // this should never fail, but it's not a critical failure
00084                  assert(false);
00085               }
00086 
00087               if (!freopen("/dev/null", "w", stderr))
00088               {
00089                  // this should never fail, but it's not a critical failure
00090                  assert(false);
00091               }
00092 
00093               if (!freopen("/dev/null", "r", stdin))
00094               {
00095                  // this should never fail, but it's not a critical failure
00096                  assert(false);
00097               }
00098            }
00099         }
00100   }
00101 
00102    pid_t get_pid_() const { return pid_; }
00103 
00104 private:
00105    pid_t pid_;
00106 };
00107 
00108 }}
00109 
00110 #endif // MOOST_PROCESS_DAEMON_LINUX_HPP__