Fork class is a simple wrapper around C library function fork(). More...
#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. |
Fork class is a simple wrapper around C library function fork().
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 | ( | Fork::state_t | state_ = WAIT_ON_EXIT , |
|
Fork::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< 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.
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_, | |||
Fork::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().