24 namespace ph = std::placeholders;
 
   79                      const std::string& executable,
 
   87     std::string getCommandLine() 
const;
 
  103     pid_t spawn(
bool dismiss);
 
  109     bool isRunning(
const pid_t pid) 
const;
 
  114     bool isAnyRunning() 
const;
 
  124     int getExitStatus(
const pid_t pid) 
const;
 
  133     void clearState(
const pid_t pid);
 
  150     char* allocateInternal(
const std::string& src);
 
  159     static bool waitForProcess(
int signum);
 
  162     static ProcessCollection process_collection_;
 
  165     std::string executable_;
 
  168     boost::shared_ptr<char*[]> args_;
 
  171     boost::shared_ptr<char*[]> vars_;
 
  174     typedef boost::shared_ptr<char[]> CStringPtr;
 
  177     std::vector<CStringPtr> storage_;
 
  183     static std::mutex mutex_;
 
  189 ProcessCollection ProcessSpawnImpl::process_collection_;
 
  190 std::mutex ProcessSpawnImpl::mutex_;
 
  193                                    const std::string& executable,
 
  196     : executable_(executable), args_(new char*[args.size() + 2]),
 
  197       vars_(new char*[vars.size() + 1]), store_(false),
 
  203     if (stat(executable_.c_str(), &st)) {
 
  207     if (!(st.st_mode & S_IEXEC)) {
 
  211     io_signal_set_->add(SIGCHLD);
 
  216     memset(args_.get(), 0, (args.size() + 2) * 
sizeof(
char*));
 
  217     memset(vars_.get(), 0, (vars.size() + 1) * 
sizeof(
char*));
 
  219     args_[0] = allocateInternal(executable_);
 
  221     for (
int i = 1; i <= args.size(); ++i) {
 
  222         args_[i] = allocateInternal(args[i - 1]);
 
  225     for (
int i = 0; i < vars.size(); ++i) {
 
  226         vars_[i] = allocateInternal(vars[i]);
 
  231     io_signal_set_->remove(SIGCHLD);
 
  233         lock_guard<std::mutex> lk(mutex_);
 
  234         process_collection_.erase(
this);
 
  240     std::ostringstream s;
 
  246     while (args_[i] != NULL) {
 
  247         s << 
" " << args_[i];
 
  255     lock_guard<std::mutex> lk(mutex_);
 
  261     } 
else if (pid == 0) {
 
  263         execve(executable_.c_str(), args_.get(), vars_.get());
 
  279     lock_guard<std::mutex> lk(mutex_);
 
  280     ProcessStates::const_iterator proc;
 
  281     if (process_collection_.find(
this) == process_collection_.end() ||
 
  282         (proc = process_collection_[
this].find(pid)) == process_collection_[
this].end()) {
 
  284                   << 
"' hasn't been spawned and it status cannot be" 
  287     return (proc->second->running_);
 
  292     lock_guard<std::mutex> lk(mutex_);
 
  293     if (process_collection_.find(
this) != process_collection_.end()) {
 
  294         for (
auto const& proc : process_collection_[
this]) {
 
  295             if (proc.second->running_) {
 
  305     lock_guard<std::mutex> lk(mutex_);
 
  306     ProcessStates::const_iterator proc;
 
  307     if (process_collection_.find(
this) == process_collection_.end() ||
 
  308         (proc = process_collection_[
this].find(pid)) == process_collection_[
this].end()) {
 
  310                   << 
"' hasn't been spawned and it status cannot be" 
  313     return (WEXITSTATUS(proc->second->status_));
 
  317 ProcessSpawnImpl::allocateInternal(
const std::string& src) {
 
  318     const size_t src_len = src.length();
 
  319     storage_.push_back(CStringPtr(
new char[src_len + 1]));
 
  321     char* dest = storage_[storage_.size() - 1].get();
 
  323     src.copy(dest, src_len);
 
  325     dest[src_len] = 
'\0';
 
  330 ProcessSpawnImpl::waitForProcess(
int) {
 
  331     lock_guard<std::mutex> lk(mutex_);
 
  334         pid_t pid = waitpid(-1, &status, WNOHANG);
 
  338         for (
auto const& instance : process_collection_) {
 
  339             auto const& proc = instance.second.find(pid);
 
  342             if (proc != instance.second.end()) {
 
  344                 proc->second->status_ = status;
 
  345                 proc->second->running_ = 
false;
 
  356                   "process (pid: " << pid << 
") which is still running");
 
  358     lock_guard<std::mutex> lk(mutex_);
 
  359     if (process_collection_.find(
this) != process_collection_.end()) {
 
  360         process_collection_[
this].erase(pid);
 
  365                            const std::string& executable,
 
  373     return (impl_->getCommandLine());
 
  378     return (impl_->spawn(dismiss));
 
  383     return (impl_->isRunning(pid));
 
  388     return (impl_->isAnyRunning());
 
  393     return (impl_->getExitStatus(pid));
 
  398     return (impl_->clearState(pid));
 
bool running_
true until the exit status is collected 
 
int getExitStatus(const pid_t pid) const 
Returns exit status of the process. 
 
ProcessSpawn(isc::asiolink::IOServicePtr io_service, const std::string &executable, const ProcessArgs &args=ProcessArgs(), const ProcessEnvVars &vars=ProcessEnvVars())
Constructor. 
 
bool isAnyRunning() const 
Checks if any of the spawned processes is still running. 
 
bool isRunning(const pid_t pid) const 
Checks if the process is still running. 
 
pid_t spawn(bool dismiss=false)
Spawn the new process. 
 
std::map< pid_t, ProcessStatePtr > ProcessStates
ProcessStates container which stores a ProcessState for each process identified by PID...
 
boost::shared_ptr< IOService > IOServicePtr
Defines a smart pointer to an IOService instance. 
 
std::string getCommandLine() const 
Returns full command line, including arguments, for the process. 
 
bool isRunning(const pid_t pid) const 
Checks if the process is still running. 
 
std::string getCommandLine() const 
Returns full command line, including arguments, for the process. 
 
~ProcessSpawnImpl()
Destructor. 
 
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments. 
 
A generic exception that is thrown if a parameter given to a method is considered invalid in that con...
 
ProcessState()
Constructor. 
 
Implements an asynchronous "signal" for IOService driven processing. 
 
boost::shared_ptr< ProcessState > ProcessStatePtr
Defines a pointer to a ProcessState. 
 
std::map< const ProcessSpawnImpl *, ProcessStates > ProcessCollection
ProcessCollection container which stores all ProcessStates for each instance of ProcessSpawnImpl. 
 
boost::shared_ptr< IOSignalSet > IOSignalSetPtr
Defines a pointer to an IOSignalSet. 
 
int status_
0 or the exit status 
 
Defines the logger used by the top-level component of kea-dhcp-ddns. 
 
Implementation of the ProcessSpawn class. 
 
void clearState(const pid_t pid)
Removes the status of the process with a specified PID. 
 
A wrapper interface for the ASIO library. 
 
Exception thrown when error occurs during spawning a process. 
 
A generic exception that is thrown if a function is called in a prohibited way. 
 
int getExitStatus(const pid_t pid) const 
Returns exit status of the process. 
 
pid_t spawn(bool dismiss)
Spawn the new process. 
 
std::vector< std::string > ProcessArgs
Type of the container holding arguments of the executable being run as a background process...
 
bool isAnyRunning() const 
Checks if any of the spawned processes is still running. 
 
void clearState(const pid_t pid)
Removes the status of the process with a specified PID. 
 
std::vector< std::string > ProcessEnvVars
Type of the container holding environment variables of the executable being run as a background proce...