ASSA::Fork Class Reference

Fork class is a simple wrapper around C library function fork(). More...

#include <Fork.h>

List of all members.

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.


Detailed Description

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 83 of file Fork.h.


Member Enumeration Documentation

enum ASSA::Fork::state_t
 

Child completion states.

Enumerator:
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 88 of file Fork.h.

00088                  { 
00089         KILL_ON_EXIT,           
00090         WAIT_ON_EXIT,           
00091         LEAVE_ALONE             
00092     };

enum ASSA::Fork::wait4status_t
 

Enumerator:
IGNORE_STATUS  Don't wait for child to complete.
COLLECT_STATUS  Wait for child to complete and collect its exit status.

Definition at line 96 of file Fork.h.

00096                        {
00097         IGNORE_STATUS,          
00098         COLLECT_STATUS          
00100     };


Constructor & Destructor Documentation

Fork::Fork state_t  exit_action_ = WAIT_ON_EXIT,
wait4status_t  catch_status_ = COLLECT_STATUS
 

Fork the current process in two immediately.

Parameters:
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 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 }

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 120 of file Fork.h.

References ASSA::FORK, and trace_with_mask.

00120 { trace_with_mask("Fork::~Fork",FORK); }


Member Function Documentation

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.

Parameters:
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.
Returns:
If wait_for_completion_ is false, returns child PID; If wait_for_completion_ is true, returns command exit status: 0 returned means that command succeeded; 1 that it failed; -1 that wait(2) failed (where it shouldn't).

Definition at line 122 of file Fork.cpp.

References DL, ASSA::FORK, 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 }

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 147 of file Fork.h.

References ASSA::ChildStatusHandler::exit_status(), and m_chstath.

00147 { return m_chstath.exit_status (); }

pid_t ASSA::Fork::getChildPID  )  const [inline]
 

Retrieve child process id.

Returns:
child pid

Definition at line 138 of file Fork.h.

References ASSA::FORK, m_pid, and trace_with_mask.

00138                               {
00139         trace_with_mask("Fork::getChildPID",FORK);
00140         return m_pid;
00141     }

bool ASSA::Fork::isChild  )  const [inline]
 

Test whether we are in child section of the code.

Returns:
true if it is parent code, false otherwise

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; }

bool ASSA::Fork::isParent  )  const [inline]
 

Test whether we are in parent section of the code.

Returns:
true if it is parent code, false otherwise

Definition at line 126 of file Fork.h.

References m_pid.

00126 { return m_pid ? true : false; }


Member Data Documentation

ChildStatusHandler ASSA::Fork::m_chstath [private]
 

Handler to catch Child's status.

Definition at line 176 of file Fork.h.

Referenced by Fork(), and get_exit_status().

SigHandler ASSA::Fork::m_local_sh [private]
 

Local signal handler.

Definition at line 173 of file Fork.h.

Referenced by Fork().

SigAction ASSA::Fork::m_old_disp [private]
 

Old signal disposition.

Definition at line 179 of file Fork.h.

Referenced by Fork().

pid_t ASSA::Fork::m_pid [private]
 

Child pid.

Definition at line 170 of file Fork.h.

Referenced by Fork(), getChildPID(), isChild(), and isParent().


The documentation for this class was generated from the following files:
Generated on Tue Jun 20 10:36:22 2006 for libassa by  doxygen 1.4.6