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 #include <sys/wait.h>
00021
00022 #include <list>
00023 using std::list;
00024
00025
00026
00027
00028
00029
00030 #if defined(__sun)
00031 #include <sys/time.h>
00032 #include <sys/resource.h>
00033 extern "C" pid_t
00034 wait4(pid_t pid, int *statusp, int options, struct rusage *rusage);
00035 #endif
00036
00037
00038 #include "assa/Assure.h"
00039 #include "assa/Singleton.h"
00040 #include "assa/EventHandler.h"
00041 #include "assa/SigHandler.h"
00042 #include "assa/SigAction.h"
00043
00044 namespace ASSA {
00045
00055 class ChildStatusHandler : public EventHandler
00056 {
00057 public:
00058 ChildStatusHandler ()
00059 : m_exit_status (-1), m_caught (false) { }
00060
00061 int handle_signal (int signum_);
00062
00066 int exit_status () const { return m_exit_status; }
00067
00070 bool caught () const { return m_caught; }
00071
00072 private:
00073 int m_exit_status;
00074 bool m_caught;
00075 };
00076
00083 class Fork {
00084 public:
00088 enum state_t {
00089 KILL_ON_EXIT,
00090 WAIT_ON_EXIT,
00091 LEAVE_ALONE
00092 };
00093
00096 enum wait4status_t {
00097 IGNORE_STATUS,
00098 COLLECT_STATUS
00100 };
00101
00112 Fork (state_t exit_action_ = WAIT_ON_EXIT,
00113 wait4status_t catch_status_ = COLLECT_STATUS);
00114
00120 ~Fork() { trace_with_mask("Fork::~Fork",FORK); }
00121
00126 bool isParent() const { return m_pid ? true : false; }
00127
00132 bool isChild() const { return !m_pid ? true : false; }
00133
00138 pid_t getChildPID() const {
00139 trace_with_mask("Fork::getChildPID",FORK);
00140 return m_pid;
00141 }
00142
00147 int get_exit_status () const { return m_chstath.exit_status (); }
00148
00164 static int fork_exec (const string& cmd_,
00165 const string& args_,
00166 wait4status_t wait_for_completion_,
00167 bool ignore_output_ = false);
00168 private:
00170 pid_t m_pid;
00171
00173 SigHandler m_local_sh;
00174
00176 ChildStatusHandler m_chstath;
00177
00179 SigAction m_old_disp;
00180 };
00181
00184 class fnode_t {
00185 public:
00187 fnode_t (pid_t pid_, Fork::state_t state_)
00188 : m_pid(pid_), m_state(state_)
00189 {
00190 trace_with_mask("fnode_t::fnode_t",FORK);
00191 }
00192
00194 pid_t getPID() const
00195 {
00196 trace_with_mask("fnode_t::getPID",FORK);
00197 return m_pid;
00198 }
00199
00201 bool needKill() const
00202 {
00203 trace_with_mask("fnode_t::needKill",FORK);
00204 return m_state == Fork::KILL_ON_EXIT ? true : false;
00205 }
00206 private:
00208 pid_t m_pid;
00209
00211 Fork::state_t m_state;
00212 };
00213
00220 class ForkList : public Singleton < ForkList >
00221 {
00222 public:
00224 ForkList () { trace_with_mask("ForkList::ForkList",FORK); }
00225
00227 ~ForkList();
00228
00230 list< fnode_t* > m_list;
00231 };
00232
00233 }
00234
00235 #endif // IS_FORK_H
00236
00237
00238
00239
00240