12 #include <boost/bind.hpp> 125 char* allocateArg(
const std::string& src)
const;
134 bool waitForProcess(
int signum);
143 std::string executable_;
151 : signals_(new
SignalSet(SIGCHLD)), process_state_(),
152 executable_(executable), args_(new char*[args.size() + 2]) {
155 signals_->setOnReceiptHandler(boost::bind(&ProcessSpawnImpl::waitForProcess,
160 memset(args_, 0, (args.size() + 2) *
sizeof(
char*));
162 args_[0] = allocateArg(executable_);
164 for (
int i = 1; i <= args.size(); ++i) {
165 args_[i] = allocateArg(args[i-1]);
172 while (args_[i] != NULL) {
182 std::ostringstream s;
188 while (args_[i] != NULL) {
189 s <<
" " << args_[i];
201 sigaddset(&sset, SIGCHLD);
202 pthread_sigmask(SIG_BLOCK, &sset, &osset);
203 if (sigismember(&osset, SIGCHLD)) {
205 "spawn() called from a thread where SIGCHLD is blocked");
213 }
else if (pid == 0) {
215 sigprocmask(SIG_SETMASK, &osset, 0);
217 if (execvp(executable_.c_str(), args_) != 0) {
228 process_state_.insert(
231 pthread_sigmask(SIG_SETMASK, &osset, 0);
234 pthread_sigmask(SIG_SETMASK, &osset, 0);
240 ProcessStates::const_iterator proc = process_state_.find(pid);
241 if (proc == process_state_.end()) {
243 <<
"' hasn't been spawned and it status cannot be" 246 return (proc->second.running_);
251 for (ProcessStates::const_iterator proc = process_state_.begin();
252 proc != process_state_.end(); ++proc) {
253 if (proc->second.running_) {
262 ProcessStates::const_iterator proc = process_state_.find(pid);
263 if (proc == process_state_.end()) {
265 <<
"' hasn't been spawned and it status cannot be" 268 return (WEXITSTATUS(proc->second.status_));
272 ProcessSpawnImpl::allocateArg(
const std::string& src)
const {
273 const size_t src_len = src.length();
275 char* dest =
new char[src_len + 1];
277 src.copy(dest, src_len);
279 dest[src_len] =
'\0';
284 ProcessSpawnImpl::waitForProcess(
int signum) {
286 if (signum != SIGCHLD) {
292 int errno_value = errno;
296 pid_t pid = waitpid(-1, &status, WNOHANG);
300 ProcessStates::iterator proc = process_state_.find(pid);
303 if (proc != process_state_.end()) {
305 proc->second.status_ = status;
306 proc->second.running_ =
false;
326 "process (pid: " << pid <<
") which is still running");
328 process_state_.erase(pid);
347 return (impl_->
spawn());
~ProcessSpawn()
Destructor.
boost::shared_ptr< SignalSet > SignalSetPtr
Pointer to the isc::util::SignalSet.
bool running_
true until the exit status is collected
ProcessSpawnImpl(const std::string &executable, const ProcessArgs &args)
Constructor.
std::string getCommandLine() const
Returns full command line, including arguments, for the process.
~ProcessSpawnImpl()
Destructor.
Exception thrown when error occurs during spawning a process.
bool isRunning(const pid_t pid) const
Checks if the process is still running.
#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...
pid_t spawn()
Spawn the new process.
bool isRunning(const pid_t pid) const
Checks if the process is still running.
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 > ProcessArgs
Type of the container holding arguments of the executable being run as a background process.
int status_
0 or the exit status
Implementation of the ProcessSpawn class.
Represents a collection of signals handled in a customized way.
Defines the logger used by the top-level component of kea-dhcp-ddns.
A generic exception that is thrown if a function is called in a prohibited way.
ProcessState()
Constructor.
int getExitStatus(const pid_t pid) const
Returns exit status of the process.
pid_t spawn()
Spawn the new process.
std::map< pid_t, ProcessState > ProcessStates
ProcessSpawn(const std::string &executable, const ProcessArgs &args=ProcessArgs())
Constructor.
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.
int getExitStatus(const pid_t pid) const
Returns exit status of the process.
std::string getCommandLine() const
Returns full command line, including arguments, for the process.