libmoost
|
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__