00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #ifndef IS_FORK_H
00013 #define IS_FORK_H
00014
00015 #include <unistd.h>
00016 #include <stdlib.h>
00017 #include <errno.h>
00018 #include <sys/types.h>
00019 #include <signal.h>
00020
00021 #ifndef WIN32
00022 # include <sys/wait.h>
00023 #endif
00024
00025 #include <list>
00026 using std::list;
00027
00028
00029
00030
00031
00032
00033 #if defined(__sun)
00034 #include <sys/time.h>
00035 #include <sys/resource.h>
00036 extern "C" pid_t
00037 wait4(pid_t pid, int *statusp, int options, struct rusage *rusage);
00038 #endif
00039
00040
00041 #include "assa/Assure.h"
00042 #include "assa/Singleton.h"
00043 #include "assa/EventHandler.h"
00044 #include "assa/SigHandler.h"
00045 #include "assa/SigAction.h"
00046
00047 namespace ASSA {
00048
00058 class ChildStatusHandler : public EventHandler
00059 {
00060 public:
00061 ChildStatusHandler ()
00062 : m_exit_status (-1), m_caught (false) { }
00063
00064 int handle_signal (int signum_);
00065
00069 int exit_status () const { return m_exit_status; }
00070
00073 bool caught () const { return m_caught; }
00074
00075 private:
00076 int m_exit_status;
00077 bool m_caught;
00078 };
00079
00086 class Fork {
00087 public:
00091 enum state_t {
00092 KILL_ON_EXIT,
00093 WAIT_ON_EXIT,
00094 LEAVE_ALONE
00095 };
00096
00099 enum wait4status_t {
00100 IGNORE_STATUS,
00101 COLLECT_STATUS
00103 };
00104
00105 #if !defined(WIN32)
00106
00116 Fork (state_t exit_action_ = WAIT_ON_EXIT,
00117 wait4status_t catch_status_ = COLLECT_STATUS);
00118
00124 ~Fork() { trace_with_mask("Fork::~Fork",FORK); }
00125
00130 bool isParent() const { return m_pid ? true : false; }
00131
00136 bool isChild() const { return !m_pid ? true : false; }
00137
00142 pid_t getChildPID() const {
00143 trace_with_mask("Fork::getChildPID",FORK);
00144 return m_pid;
00145 }
00146
00151 int get_exit_status () const { return m_chstath.exit_status (); }
00152
00153 #endif // !defined(WIN32)
00154
00170 static int fork_exec (const string& cmd_,
00171 const string& args_,
00172 wait4status_t wait_for_completion_,
00173 bool ignore_output_ = false);
00174
00175 #if !defined(WIN32)
00176 private:
00178 pid_t m_pid;
00179
00181 SigHandler m_local_sh;
00182
00184 ChildStatusHandler m_chstath;
00185
00187 SigAction m_old_disp;
00188
00189 #endif // !defined(WIN32)
00190
00191 };
00192
00195 class fnode_t {
00196 public:
00198 fnode_t (pid_t pid_, Fork::state_t state_)
00199 : m_pid(pid_), m_state(state_)
00200 {
00201 trace_with_mask("fnode_t::fnode_t",FORK);
00202 }
00203
00205 pid_t getPID() const
00206 {
00207 trace_with_mask("fnode_t::getPID",FORK);
00208 return m_pid;
00209 }
00210
00212 bool needKill() const
00213 {
00214 trace_with_mask("fnode_t::needKill",FORK);
00215 return m_state == Fork::KILL_ON_EXIT ? true : false;
00216 }
00217 private:
00219 pid_t m_pid;
00220
00222 Fork::state_t m_state;
00223 };
00224
00231 class ForkList : public Singleton < ForkList >
00232 {
00233 public:
00235 ForkList () { trace_with_mask("ForkList::ForkList",FORK); }
00236
00238 ~ForkList();
00239
00241 list< fnode_t* > m_list;
00242 };
00243
00244 }
00245
00246 #endif // IS_FORK_H
00247
00248
00249
00250
00251