00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 #include <signal.h>
00011 #ifdef _MSC_VER
00012     #include <windows.h>
00013 #else
00014     #include <fcntl.h>
00015     #include <unistd.h>
00016     #include <sys/stat.h>
00017 #endif
00018 
00019 #include <pion/config.hpp>
00020 #include <pion/process.hpp>
00021 
00022 
00023 namespace pion {    
00024     
00025 
00026     
00027 boost::once_flag                process::m_instance_flag = BOOST_ONCE_INIT;
00028 process::config_type *process::m_config_ptr = NULL;
00029 
00030     
00031 
00032     
00033 void process::shutdown(void)
00034 {
00035     config_type& cfg = get_config();
00036     boost::mutex::scoped_lock shutdown_lock(cfg.shutdown_mutex);
00037     if (! cfg.shutdown_now) {
00038         cfg.shutdown_now = true;
00039         cfg.shutdown_cond.notify_all();
00040     }
00041 }
00042 
00043 void process::wait_for_shutdown(void)
00044 {
00045     config_type& cfg = get_config();
00046     boost::mutex::scoped_lock shutdown_lock(cfg.shutdown_mutex);
00047     while (! cfg.shutdown_now)
00048         cfg.shutdown_cond.wait(shutdown_lock);
00049 }
00050 
00051 void process::create_config(void)
00052 {
00053     static config_type UNIQUE_PION_PROCESS_CONFIG;
00054     m_config_ptr = &UNIQUE_PION_PROCESS_CONFIG;
00055 }
00056 
00057 
00058 
00059 #ifdef _MSC_VER
00060 
00061 BOOL WINAPI console_ctrl_handler(DWORD ctrl_type)
00062 {
00063     switch(ctrl_type) {
00064         case CTRL_C_EVENT:
00065         case CTRL_BREAK_EVENT:
00066         case CTRL_CLOSE_EVENT:
00067         case CTRL_SHUTDOWN_EVENT:
00068             process::shutdown();
00069             return TRUE;
00070         default:
00071             return FALSE;
00072     }
00073 }
00074 
00075 void process::initialize(void)
00076 {
00077     SetConsoleCtrlHandler(console_ctrl_handler, TRUE);
00078 }
00079 
00080 void process::daemonize(void)
00081 {
00082     
00083 }
00084 
00085 #else   // NOT #ifdef _MSC_VER
00086 
00087 void handle_signal(int sig)
00088 {
00089     process::shutdown();
00090 }
00091 
00092 void process::initialize(void)
00093 {
00094     signal(SIGPIPE, SIG_IGN);
00095     signal(SIGCHLD, SIG_IGN);
00096     signal(SIGTSTP, SIG_IGN);
00097     signal(SIGTTOU, SIG_IGN);
00098     signal(SIGTTIN, SIG_IGN);
00099     signal(SIGHUP, SIG_IGN);
00100     signal(SIGINT, handle_signal);
00101     signal(SIGTERM, handle_signal);
00102 }
00103 
00104 void process::daemonize(void)
00105 {
00106     
00107     
00108     
00109     
00110     if(getppid()==1) return;
00111     
00112     
00113     int i = fork();
00114     if (i<0) exit(1);   
00115     if (i>0) exit(0);   
00116     
00117     
00118     
00119     
00120     setsid();
00121     
00122     
00123     for (i=getdtablesize();i>=0;--i) close(i);
00124     
00125     
00126     i=open("/dev/null",O_RDWR);
00127     if (i != -1) {
00128         if (dup(i) == -1) {}
00129         if (dup(i) == -1) {}
00130     }
00131     
00132     
00133     umask(027);
00134 }
00135 
00136 #endif  // #ifdef _MSC_VER
00137 
00138 }