#include <Fork.h>
Public Types | |
enum | state_t { KILL_ON_EXIT, WAIT_ON_EXIT, LEAVE_ALONE } |
Child completion states. More... | |
enum | wait4status_t { IGNORE_STATUS, COLLECT_STATUS } |
Public Member Functions | |
Fork (state_t exit_action_=WAIT_ON_EXIT, wait4status_t catch_status_=COLLECT_STATUS) | |
Fork the current process in two immediately. | |
~Fork () | |
Destructor. | |
bool | isParent () const |
Test whether we are in parent section of the code. | |
bool | isChild () const |
Test whether we are in child section of the code. | |
pid_t | getChildPID () const |
Retrieve child process id. | |
int | get_exit_status () const |
Retrieve exit status of a child process if the constructor's parameter catch_status_ was set to TRUE. | |
Static Public Member Functions | |
static int | fork_exec (const string &cmd_, const string &args_, wait4status_t wait_for_completion_, bool ignore_output_=false) |
Execute an external command. | |
Private Attributes | |
pid_t | m_pid |
Child pid. | |
SigHandler | m_local_sh |
Local signal handler. | |
ChildStatusHandler | m_chstath |
Handler to catch Child's status. | |
SigAction | m_old_disp |
Old signal disposition. |
Main advantage of using Fork over fork() is that child termination process is handles internally by Fork class static destructor.
Definition at line 83 of file Fork.h.
|
Child completion states.
Definition at line 88 of file Fork.h. 00088 { 00089 KILL_ON_EXIT, 00090 WAIT_ON_EXIT, 00091 LEAVE_ALONE 00092 };
|
|
Definition at line 96 of file Fork.h. 00096 { 00097 IGNORE_STATUS, 00098 COLLECT_STATUS 00100 };
|
|
Fork the current process in two immediately.
Definition at line 60 of file Fork.cpp. References ASSA::ChildStatusHandler::caught(), COLLECT_STATUS, EL, ASSA::ERROR, ASSA::FORK, ASSA::Singleton< ForkList >::get_instance(), ASSA::SigHandler::install(), LEAVE_ALONE, m_chstath, m_local_sh, m_old_disp, m_pid, ASSA::SigHandler::remove(), and trace_with_mask. 00061 { 00062 trace_with_mask("Fork::Fork",FORK); 00063 00064 if (catch_status_ == COLLECT_STATUS) { 00065 m_local_sh.install (SIGCHLD, &m_chstath, 0, 0, &m_old_disp); 00066 } 00067 00068 if ((m_pid = fork()) < 0) { 00069 EL((ERROR,"failed to fork() - out of swap space?\n")); 00070 exit (1); // die right here 00071 } 00072 00073 if (m_pid) { // The Parent 00074 if (state_ != LEAVE_ALONE) { 00075 ForkList::get_instance()-> 00076 m_list.push_back (new fnode_t (m_pid, state_)); 00077 } 00078 if (catch_status_ == COLLECT_STATUS) { 00079 if (! m_chstath.caught ()) { 00080 pause (); 00081 } 00082 m_local_sh.remove (SIGCHLD, &m_chstath, &m_old_disp, 0); 00083 } 00084 } 00085 }
|
|
Destructor. Doesn't really do anything. All children will be terminated according to state set when process terminates. Definition at line 120 of file Fork.h. References ASSA::FORK, and trace_with_mask. 00120 { trace_with_mask("Fork::~Fork",FORK); }
|
|
Execute an external command. Conveniently wraps fork()/execvp()/wait() sequence of calls.
Definition at line 122 of file Fork.cpp. References DL, EL, ASSA::ERROR, ASSA::FORK, LEAVE_ALONE, ASSA::CmdLineOpts::str_to_argv(), and trace_with_mask. 00126 { 00127 trace_with_mask("Fork[static]::fork_exec",FORK); 00128 00129 DL((FORK,"exec \"%s %s\")\n", cmd_.c_str (), args_.c_str ())); 00130 if (cmd_.size () == 0) { 00131 return -1; 00132 } 00133 00134 Fork f (Fork::LEAVE_ALONE, wait_for_completion_); 00135 00136 if (f.isChild ()) { 00137 string arg_list (cmd_); 00138 arg_list += " " + args_; 00139 int argc = 0; 00140 char** argv = 0; 00141 CmdLineOpts::str_to_argv (arg_list, argc, argv); 00142 00146 if (ignore_output_) { 00147 for (int i = 0; i < 1024; i++) { 00148 (void) close(i); 00149 } 00150 pid_t nullfd = open("/dev/null", O_WRONLY | O_CREAT, 0666); 00151 if (nullfd == -1) { 00152 syslog (LOG_ERR,"failed to open \"/dev/null\""); 00153 _exit (-1); 00154 } 00155 00156 (void) dup2 (nullfd, 1); 00157 (void) dup2 (nullfd, 2); 00158 (void) close (nullfd); 00159 } 00160 00161 execvp (cmd_.c_str (), argv); 00162 00163 EL((ERROR,"fork_exec (\"%s\") failed\n", cmd_.c_str ())); 00164 _exit (-1); 00165 } 00166 00167 if (! wait_for_completion_) { 00168 return f.getChildPID (); 00169 } 00170 00171 return f.get_exit_status (); 00172 }
|
|
Retrieve exit status of a child process if the constructor's parameter catch_status_ was set to TRUE.
Definition at line 147 of file Fork.h. References ASSA::ChildStatusHandler::exit_status(), and m_chstath. 00147 { return m_chstath.exit_status (); }
|
|
Retrieve child process id.
Definition at line 138 of file Fork.h. References ASSA::FORK, m_pid, and trace_with_mask. Referenced by ASSA::Pipe::open(). 00138 { 00139 trace_with_mask("Fork::getChildPID",FORK); 00140 return m_pid; 00141 }
|
|
Test whether we are in child section of the code.
Definition at line 132 of file Fork.h. References m_pid. Referenced by ASSA::GenServer::become_daemon(), and ASSA::Pipe::open(). 00132 { return !m_pid ? true : false; }
|
|
Test whether we are in parent section of the code.
Definition at line 126 of file Fork.h. References m_pid. 00126 { return m_pid ? true : false; }
|
|
Handler to catch Child's status.
Definition at line 176 of file Fork.h. Referenced by Fork(), and get_exit_status(). |
|
Local signal handler.
Definition at line 173 of file Fork.h. Referenced by Fork(). |
|
Old signal disposition.
Definition at line 179 of file Fork.h. Referenced by Fork(). |
|
Child pid.
Definition at line 170 of file Fork.h. Referenced by Fork(), getChildPID(), isChild(), and isParent(). |