#include <Fork.h>
Public Types | |
KILL_ON_EXIT | |
Kill all childer on exit. | |
WAIT_ON_EXIT | |
Wait for all children to exit. | |
LEAVE_ALONE | |
Ignore all running children on exit. | |
IGNORE_STATUS | |
Don't wait for child to complete. | |
COLLECT_STATUS | |
Wait for child to complete and collect its exit status. | |
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 86 of file Fork.h.
enum ASSA::Fork::state_t |
Child completion states.
KILL_ON_EXIT | Kill all childer on exit. |
WAIT_ON_EXIT | Wait for all children to exit. |
LEAVE_ALONE | Ignore all running children on exit. |
Definition at line 91 of file Fork.h.
00091 { 00092 KILL_ON_EXIT, 00093 WAIT_ON_EXIT, 00094 LEAVE_ALONE 00095 };
IGNORE_STATUS | Don't wait for child to complete. |
COLLECT_STATUS | Wait for child to complete and collect its exit status. |
Definition at line 99 of file Fork.h.
00099 { 00100 IGNORE_STATUS, 00101 COLLECT_STATUS 00103 };
Fork::Fork | ( | state_t | exit_action_ = WAIT_ON_EXIT , |
|
wait4status_t | catch_status_ = COLLECT_STATUS | |||
) |
Fork the current process in two immediately.
exit_action_ | Specify (default=WAIT_ON_EXIT) whether to wait for the child to finish or kill it with SIGTERM on process exit. | |
catch_status_ | If true (default=COLLECT_STATUS), pause for the child to exit and collect its exit status. |
Definition at line 160 of file Fork.cpp.
References ASSA::ASSAERR, ASSA::ChildStatusHandler::caught(), COLLECT_STATUS, EL, ASSA::FORK, ASSA::Singleton< T >::get_instance(), ASSA::SigHandler::install(), LEAVE_ALONE, m_chstath, m_local_sh, m_old_disp, m_pid, ASSA::SigHandler::remove(), and trace_with_mask.
00161 { 00162 trace_with_mask("Fork::Fork",FORK); 00163 00164 if (catch_status_ == COLLECT_STATUS) { 00165 m_local_sh.install (SIGCHLD, &m_chstath, 0, 0, &m_old_disp); 00166 } 00167 00168 if ((m_pid = fork()) < 0) { 00169 EL((ASSAERR,"failed to fork() - out of swap space?\n")); 00170 exit (1); // die right here 00171 } 00172 00173 if (m_pid) { // The Parent 00174 if (state_ != LEAVE_ALONE) { 00175 ForkList::get_instance()-> 00176 m_list.push_back (new fnode_t (m_pid, state_)); 00177 } 00178 if (catch_status_ == COLLECT_STATUS) { 00179 if (! m_chstath.caught ()) { 00180 pause (); 00181 } 00182 m_local_sh.remove (SIGCHLD, &m_chstath, &m_old_disp, 0); 00183 } 00184 } 00185 }
ASSA::Fork::~Fork | ( | ) | [inline] |
Destructor.
Doesn't really do anything. All children will be terminated according to state set when process terminates.
Definition at line 124 of file Fork.h.
References ASSA::FORK, and trace_with_mask.
00124 { trace_with_mask("Fork::~Fork",FORK); }
int Fork::fork_exec | ( | const string & | cmd_, | |
const string & | args_, | |||
wait4status_t | wait_for_completion_, | |||
bool | ignore_output_ = false | |||
) | [static] |
Execute an external command.
Conveniently wraps fork()/execvp()/wait() sequence of calls.
cmd_ | Command to execute. | |
args_ | Command arguments as one string. | |
wait_for_completion_ | If set to true, blocks until child exits; false otherwise. | |
ignore_output_ | Discard child's output to stdout/stderr. |
Close all file descriptors and reduped stdout/stderr to /dev/null
Definition at line 63 of file Fork.cpp.
References ASSA::ASSAERR, DL, EL, ASSA::FORK, get_exit_status(), getChildPID(), isChild(), LEAVE_ALONE, ASSA::CmdLineOpts::str_to_argv(), and trace_with_mask.
00067 { 00068 trace_with_mask("Fork[static]::fork_exec",FORK); 00069 00070 DL((FORK,"exec \"%s %s\")\n", cmd_.c_str (), args_.c_str ())); 00071 if (cmd_.size () == 0) { 00072 return -1; 00073 } 00074 00075 #if defined(WIN32) 00076 00077 return -1; // NOT IMPLEMENTED YET 00078 00079 #else 00080 00081 Fork f (Fork::LEAVE_ALONE, wait_for_completion_); 00082 00083 if (f.isChild ()) { 00084 string arg_list (cmd_); 00085 arg_list += " " + args_; 00086 int argc = 0; 00087 char** argv = 0; 00088 CmdLineOpts::str_to_argv (arg_list, argc, argv); 00089 00093 if (ignore_output_) { 00094 for (int i = 0; i < 1024; i++) { 00095 (void) close(i); 00096 } 00097 pid_t nullfd = open("/dev/null", O_WRONLY | O_CREAT, 0666); 00098 if (nullfd == -1) { 00099 syslog (LOG_ERR,"failed to open \"/dev/null\""); 00100 _exit (-1); 00101 } 00102 00103 (void) dup2 (nullfd, 1); 00104 (void) dup2 (nullfd, 2); 00105 (void) close (nullfd); 00106 } 00107 00108 execvp (cmd_.c_str (), argv); 00109 00110 EL((ASSAERR,"fork_exec (\"%s\") failed\n", cmd_.c_str ())); 00111 _exit (-1); 00112 } 00113 00114 if (! wait_for_completion_) { 00115 return f.getChildPID (); 00116 } 00117 00118 return f.get_exit_status (); 00119 00120 #endif // defined(WIN32) 00121 }
int ASSA::Fork::get_exit_status | ( | ) | const [inline] |
Retrieve exit status of a child process if the constructor's parameter catch_status_ was set to TRUE.
Definition at line 151 of file Fork.h.
References ASSA::ChildStatusHandler::exit_status(), and m_chstath.
Referenced by fork_exec().
00151 { return m_chstath.exit_status (); }
pid_t ASSA::Fork::getChildPID | ( | ) | const [inline] |
Retrieve child process id.
Definition at line 142 of file Fork.h.
References ASSA::FORK, m_pid, and trace_with_mask.
Referenced by fork_exec(), and ASSA::Pipe::open().
00142 { 00143 trace_with_mask("Fork::getChildPID",FORK); 00144 return m_pid; 00145 }
bool ASSA::Fork::isChild | ( | ) | const [inline] |
Test whether we are in child section of the code.
Definition at line 136 of file Fork.h.
References m_pid.
Referenced by ASSA::GenServer::become_daemon(), fork_exec(), and ASSA::Pipe::open().
00136 { return !m_pid ? true : false; }
bool ASSA::Fork::isParent | ( | ) | const [inline] |
ChildStatusHandler ASSA::Fork::m_chstath [private] |
Handler to catch Child's status.
Definition at line 184 of file Fork.h.
Referenced by Fork(), and get_exit_status().
SigHandler ASSA::Fork::m_local_sh [private] |
SigAction ASSA::Fork::m_old_disp [private] |
pid_t ASSA::Fork::m_pid [private] |
Child pid.
Definition at line 178 of file Fork.h.
Referenced by Fork(), getChildPID(), isChild(), and isParent().