Back to index

nordugrid-arc-nox  1.1.0~rc6
Public Member Functions | Protected Member Functions | Protected Attributes | Private Member Functions | Friends
Arc::Run Class Reference

This class runs external executable. More...

#include <Run.h>

Collaboration diagram for Arc::Run:
Collaboration graph
[legend]

List of all members.

Public Member Functions

 Run (const std::string &cmdline)
 Constructor preapres object to run cmdline.
 Run (const std::list< std::string > &argv)
 Constructor preapres object to run executable and arguments specified in argv.
 ~Run (void)
 Destructor kills running executable and releases associated resources.
 operator bool (void)
 Returns true if object is valid.
bool operator! (void)
 Returns true if object is invalid.
bool Start (void)
 Starts running executable.
bool Wait (int timeout)
 Wait till execution finished or till timeout seconds expires.
bool Wait (void)
 Wait till execution finished.
int Result (void)
 Returns exit code of execution.
bool Running (void)
 Return true if execution is going on.
int ReadStdout (int timeout, char *buf, int size)
 Read from stdout handle of running executable.
int ReadStderr (int timeout, char *buf, int size)
 Read from stderr handle of running executable.
int WriteStdin (int timeout, const char *buf, int size)
 Write to stdin handle of running executable.
void AssignStdout (std::string &str)
 Associate stdout handle of executable with string.
void AssignStderr (std::string &str)
 Associate stderr handle of executable with string.
void AssignStdin (std::string &str)
 Associate stdin handle of executable with string.
void KeepStdout (bool keep=true)
 Keep stdout same as parent's if keep = true.
void KeepStderr (bool keep=true)
 Keep stderr same as parent's if keep = true.
void KeepStdin (bool keep=true)
 Keep stdin same as parent's if keep = true.
void CloseStdout (void)
 Closes pipe associated with stdout handle.
void CloseStderr (void)
 Closes pipe associated with stderr handle.
void CloseStdin (void)
 Closes pipe associated with stdin handle.
void AssignInitializer (void(*initializer_func)(void *), void *initializer_arg)
void AssignKicker (void(*kicker_func)(void *), void *kicker_arg)
void AssignWorkingDirectory (std::string &wd)
 Assign working direcotry of the running process.
void Kill (int timeout)
 Kill running executable.
void Abandon (void)
 Detach this object from running process.

Protected Member Functions

bool stdout_handler (Glib::IOCondition cond)
bool stderr_handler (Glib::IOCondition cond)
bool stdin_handler (Glib::IOCondition cond)
void child_handler (Glib::Pid pid, int result)

Protected Attributes

std::string working_directory
int stdout_
int stderr_
int stdin_
std::string * stdout_str_
std::string * stderr_str_
std::string * stdin_str_
bool stdout_keep_
bool stderr_keep_
bool stdin_keep_
sigc::connection stdout_conn_
sigc::connection stderr_conn_
sigc::connection stdin_conn_
sigc::connection child_conn_
Pidpid_
Glib::ArrayHandle< std::string > argv_
void(* initializer_func_ )(void *)
void * initializer_arg_
void(* kicker_func_ )(void *)
void * kicker_arg_
bool started_
bool running_
bool abandoned_
int result_
Glib::Mutex lock_
Glib::Cond cond_

Private Member Functions

 Run (const Run &)
Runoperator= (Run &)

Friends

class RunPump

Detailed Description

This class runs external executable.

It is possible to read/write it's standard handles or to redirect then to std::string elements.

Definition at line 16 of file Run.h.


Constructor & Destructor Documentation

Arc::Run::Run ( const Run ) [private]
Arc::Run::Run ( const std::string &  cmdline)

Constructor preapres object to run cmdline.

Definition at line 250 of file Run_unix.cpp.

    : working_directory("."),
      stdout_(-1),
      stderr_(-1),
      stdin_(-1),
      stdout_str_(NULL),
      stderr_str_(NULL),
      stdin_str_(NULL),
      stdout_keep_(false),
      stderr_keep_(false),
      stdin_keep_(false),
      pid_(NULL),
      argv_(Glib::shell_parse_argv(cmdline)),
      initializer_func_(NULL),
      initializer_arg_(NULL),
      kicker_func_(NULL),
      started_(false),
      running_(false),
      abandoned_(false),
      result_(-1) {
    pid_ = new Pid;
  }
Arc::Run::Run ( const std::list< std::string > &  argv)

Constructor preapres object to run executable and arguments specified in argv.

Definition at line 273 of file Run_unix.cpp.

    : working_directory("."),
      stdout_(-1),
      stderr_(-1),
      stdin_(-1),
      stdout_str_(NULL),
      stderr_str_(NULL),
      stdin_str_(NULL),
      pid_(0),
      argv_(argv),
      initializer_func_(NULL),
      initializer_arg_(NULL),
      kicker_func_(NULL),
      started_(false),
      running_(false),
      abandoned_(false),
      result_(-1) {
    pid_ = new Pid;
  }
Arc::Run::~Run ( void  )

Destructor kills running executable and releases associated resources.

Definition at line 293 of file Run_unix.cpp.

                {
    if(*this) {
      if(!abandoned_) Kill(0);
      CloseStdout();
      CloseStderr();
      CloseStdin();
      RunPump::Instance().Remove(this);
    };
  }

Here is the call graph for this function:


Member Function Documentation

void Arc::Run::Abandon ( void  )

Detach this object from running process.

After calling this method instance is not associated with external process anymore. As result destructor will not kill process.

Definition at line 361 of file Run_unix.cpp.

                        {
    if(*this) {
      CloseStdout();
      CloseStderr();
      CloseStdin();
      abandoned_=true;
    }
  }

Here is the call graph for this function:

void Arc::Run::AssignInitializer ( void(*)(void *)  initializer_func,
void *  initializer_arg 
)

Definition at line 632 of file Run_unix.cpp.

                                                                                        {
    if (!running_) {
      initializer_arg_ = initializer_arg;
      initializer_func_ = initializer_func;
    }
  }

Here is the caller graph for this function:

void Arc::Run::AssignKicker ( void(*)(void *)  kicker_func,
void *  kicker_arg 
)

Definition at line 639 of file Run_unix.cpp.

                                                                         {
    if (!running_) {
      kicker_arg_ = kicker_arg;
      kicker_func_ = kicker_func;
    }
  }

Here is the caller graph for this function:

void Arc::Run::AssignStderr ( std::string &  str)

Associate stderr handle of executable with string.

This method must be called before Start(). str object must be valid as long as this object exists.

Definition at line 607 of file Run_unix.cpp.

                                       {
    if (!running_)
      stderr_str_ = &str;
  }

Here is the caller graph for this function:

void Arc::Run::AssignStdin ( std::string &  str)

Associate stdin handle of executable with string.

This method must be called before Start(). str object must be valid as long as this object exists.

Definition at line 612 of file Run_unix.cpp.

                                      {
    if (!running_)
      stdin_str_ = &str;
  }

Here is the caller graph for this function:

void Arc::Run::AssignStdout ( std::string &  str)

Associate stdout handle of executable with string.

This method must be called before Start(). str object must be valid as long as this object exists.

Definition at line 602 of file Run_unix.cpp.

                                       {
    if (!running_)
      stdout_str_ = &str;
  }

Here is the caller graph for this function:

void Arc::Run::AssignWorkingDirectory ( std::string &  wd) [inline]

Assign working direcotry of the running process.

Definition at line 140 of file Run.h.

                                               {
      working_directory = wd;
    }

Here is the caller graph for this function:

void Arc::Run::child_handler ( Glib::Pid  pid,
int  result 
) [protected]

Definition at line 430 of file Run_unix.cpp.

                                             {
    if (stdout_str_)
      for (;;)
        if (!stdout_handler(Glib::IO_IN))
          break;
    if (stderr_str_)
      for (;;)
        if (!stderr_handler(Glib::IO_IN))
          break;
    CloseStdout();
    CloseStderr();
    CloseStdin();
    lock_.lock();
    cond_.signal();
    // There is reference in Glib manual that 'result' is same
    // as returned by waitpid. It is not clear how it works for
    // windows but atleast for *nix we can use waitpid related
    // macros.
    if(WIFEXITED(result)) {
      result_ = WEXITSTATUS(result);
    } else {
      result_ = -1;
    }
    running_ = false;
    lock_.unlock();
    if (kicker_func_)
      (*kicker_func_)(kicker_arg_);
  }

Here is the call graph for this function:

Here is the caller graph for this function:

void Arc::Run::CloseStderr ( void  )

Closes pipe associated with stderr handle.

Definition at line 466 of file Run_unix.cpp.

                            {
    if (stderr_ != -1)
      ::close(stderr_);
    stderr_ = -1;
    SAFE_DISCONNECT(stderr_conn_);
  }

Here is the caller graph for this function:

void Arc::Run::CloseStdin ( void  )

Closes pipe associated with stdin handle.

Definition at line 473 of file Run_unix.cpp.

                           {
    if (stdin_ != -1)
      ::close(stdin_);
    stdin_ = -1;
    SAFE_DISCONNECT(stdin_conn_);
  }

Here is the caller graph for this function:

void Arc::Run::CloseStdout ( void  )

Closes pipe associated with stdout handle.

Definition at line 459 of file Run_unix.cpp.

                            {
    if (stdout_ != -1)
      ::close(stdout_);
    stdout_ = -1;
    SAFE_DISCONNECT(stdout_conn_);
  }

Here is the caller graph for this function:

void Arc::Run::KeepStderr ( bool  keep = true)

Keep stderr same as parent's if keep = true.

Definition at line 622 of file Run_unix.cpp.

                                {
    if (!running_)
      stderr_keep_ = keep;
  }

Here is the caller graph for this function:

void Arc::Run::KeepStdin ( bool  keep = true)

Keep stdin same as parent's if keep = true.

Definition at line 627 of file Run_unix.cpp.

                               {
    if (!running_)
      stdin_keep_ = keep;
  }

Here is the caller graph for this function:

void Arc::Run::KeepStdout ( bool  keep = true)

Keep stdout same as parent's if keep = true.

Definition at line 617 of file Run_unix.cpp.

                                {
    if (!running_)
      stdout_keep_ = keep;
  }

Here is the caller graph for this function:

void Arc::Run::Kill ( int  timeout)

Kill running executable.

First soft kill signal (SIGTERM) is sent to executable. If after timeout seconds executable is still running it's killed completely. Curently this method does not work for Windows OS

Definition at line 344 of file Run_unix.cpp.

                            {
#ifndef HAVE_GLIBMM_CHILDWATCH
    Wait(0);
#endif
    if (!running_)
      return;
    if (timeout > 0) {
      // Kill softly
      ::kill(pid_->pid(), SIGTERM);
      Wait(timeout);
    }
    if (!running_)
      return;
    // Kill with no merci
    ::kill(pid_->pid(), SIGKILL);
  }

Here is the call graph for this function:

Here is the caller graph for this function:

Arc::Run::operator bool ( void  ) [inline]

Returns true if object is valid.

Definition at line 69 of file Run.h.

                        {
      return argv_.size() != 0;
    }
bool Arc::Run::operator! ( void  ) [inline]

Returns true if object is invalid.

Definition at line 73 of file Run.h.

                         {
      return argv_.size() == 0;
    }
Run& Arc::Run::operator= ( Run ) [private]
int Arc::Run::ReadStderr ( int  timeout,
char *  buf,
int  size 
)

Read from stderr handle of running executable.

Parameter timeout specifies upper limit for which method will block in milliseconds. Negative means infinite. This method may be used while stderr is directed to string. But result is unpredictable. Returns number of read bytes.

Definition at line 492 of file Run_unix.cpp.

                                                      {
    if (stderr_ == -1)
      return -1;
    // TODO: do it through context for timeout
    pollfd fd;
    fd.fd = stderr_; fd.events = POLLIN; fd.revents = 0;
    int err = poll(&fd, 1, timeout);
    if(err <= 0) return err;
    if(!(fd.revents & POLLIN)) return -1;
    return ::read(stderr_, buf, size);
  }

Here is the caller graph for this function:

int Arc::Run::ReadStdout ( int  timeout,
char *  buf,
int  size 
)

Read from stdout handle of running executable.

Parameter timeout specifies upper limit for which method will block in milliseconds. Negative means infinite. This method may be used while stdout is directed to string. But result is unpredictable. Returns number of read bytes.

Definition at line 480 of file Run_unix.cpp.

                                                      {
    if (stdout_ == -1)
      return -1;
    // TODO: do it through context for timeout?
    pollfd fd;
    fd.fd = stdout_; fd.events = POLLIN; fd.revents = 0;
    int err = poll(&fd, 1, timeout);
    if(err <= 0) return err;
    if(!(fd.revents & POLLIN)) return -1;
    return ::read(stdout_, buf, size);
  }

Here is the caller graph for this function:

int Arc::Run::Result ( void  ) [inline]

Returns exit code of execution.

Definition at line 85 of file Run.h.

                     {
      return result_;
    }

Here is the caller graph for this function:

bool Arc::Run::Running ( void  )

Return true if execution is going on.

Definition at line 516 of file Run_unix.cpp.

                        {
#ifdef HAVE_GLIBMM_CHILDWATCH
    return running_;
#else
    Wait(0);
    return running_;
#endif
  }

Here is the call graph for this function:

Here is the caller graph for this function:

bool Arc::Run::Start ( void  )

Starts running executable.

This method may be called only once.

Definition at line 303 of file Run_unix.cpp.

                      {
    if (started_)
      return false;
    if (argv_.size() < 1)
      return false;
    RunPump& pump = RunPump::Instance();
    RunInitializerArgument *arg = NULL;
    try {
      UserSwitch usw(0,0);
      running_ = true;
      Glib::Pid pid;
      arg = new RunInitializerArgument(initializer_func_, initializer_arg_);
      spawn_async_with_pipes(working_directory, argv_,
                             Glib::SpawnFlags(Glib::SPAWN_DO_NOT_REAP_CHILD),
                             sigc::mem_fun(*arg, &RunInitializerArgument::Run),
                             &pid,
                             stdin_keep_  ? NULL : &stdin_,
                             stdout_keep_ ? NULL : &stdout_,
                             stderr_keep_ ? NULL : &stderr_);
      *pid_ = pid;
      if (!stdin_keep_)
        fcntl(stdin_, F_SETFL, fcntl(stdin_, F_GETFL) | O_NONBLOCK);
      if (!stdout_keep_)
        fcntl(stdout_, F_SETFL, fcntl(stdout_, F_GETFL) | O_NONBLOCK);
      if (!stderr_keep_)
        fcntl(stderr_, F_SETFL, fcntl(stderr_, F_GETFL) | O_NONBLOCK);
      started_ = true;
    } catch (Glib::Exception& e) {
      running_ = false;
      // TODO: report error
      return false;
    } catch (std::exception& e) {
      running_ = false;
      return false;
    };
    pump.Add(this);
    if (arg)
      delete arg;
    return true;
  }

Here is the call graph for this function:

Here is the caller graph for this function:

bool Arc::Run::stderr_handler ( Glib::IOCondition  cond) [protected]

Definition at line 388 of file Run_unix.cpp.

                                          {
    if (stderr_str_) {
      char buf[256];
      int l = ReadStderr(0, buf, sizeof(buf));
      if ((l == 0) || (l == -1)) {
        CloseStderr();
        return false;
      }
      else
        stderr_str_->append(buf, l);
    }
    else {
      // Event shouldn't happen if not expected

    }
    return true;
  }

Here is the call graph for this function:

Here is the caller graph for this function:

bool Arc::Run::stdin_handler ( Glib::IOCondition  cond) [protected]

Definition at line 406 of file Run_unix.cpp.

                                         {
    if (stdin_str_) {
      if (stdin_str_->length() == 0) {
        CloseStdin();
        stdin_str_ = NULL;
      }
      else {
        int l = WriteStdin(0, stdin_str_->c_str(), stdin_str_->length());
        if (l == -1) {
          CloseStdin();
          return false;
        }
        else
          // Not very effective
          *stdin_str_ = stdin_str_->substr(l);
      }
    }
    else {
      // Event shouldn't happen if not expected

    }
    return true;
  }

Here is the call graph for this function:

Here is the caller graph for this function:

bool Arc::Run::stdout_handler ( Glib::IOCondition  cond) [protected]

Definition at line 370 of file Run_unix.cpp.

                                          {
    if (stdout_str_) {
      char buf[256];
      int l = ReadStdout(0, buf, sizeof(buf));
      if ((l == 0) || (l == -1)) {
        CloseStdout();
        return false;
      }
      else
        stdout_str_->append(buf, l);
    }
    else {
      // Event shouldn't happen if not expected

    }
    return true;
  }

Here is the call graph for this function:

Here is the caller graph for this function:

bool Arc::Run::Wait ( int  timeout)

Wait till execution finished or till timeout seconds expires.

Returns true if execution is complete.

Definition at line 525 of file Run_unix.cpp.

                            {
    if (!started_)
      return false;
    if (!running_)
      return true;
    Glib::TimeVal till;
    till.assign_current_time();
    till += timeout;
    lock_.lock();
    while (running_) {
      Glib::TimeVal t;
      t.assign_current_time();
      t.subtract(till);
#ifdef HAVE_GLIBMM_CHILDWATCH
      if (!t.negative())
        break;
      cond_.timed_wait(lock_, till);
#else
      int status;
      int r = waitpid(pid_->pid(), &status, WNOHANG);
      if (r == 0) {
        if (!t.negative())
          break;
        lock_.unlock();
        sleep(1);
        lock_.lock();
        continue;
      }
      if (r == -1) // Child lost?
        status = -1;
      else
        status = WEXITSTATUS(status);
      // Child exited
      lock_.unlock();
      child_handler(pid_->pid(), status << 8);
      lock_.lock();
#endif
    }
    lock_.unlock();
    return (!running_);
  }

Here is the call graph for this function:

Here is the caller graph for this function:

bool Arc::Run::Wait ( void  )

Wait till execution finished.

Definition at line 567 of file Run_unix.cpp.

                     {
    if (!started_)
      return false;
    if (!running_)
      return true;
    lock_.lock();
    Glib::TimeVal till;
    while (running_) {
#ifdef HAVE_GLIBMM_CHILDWATCH
      till.assign_current_time();
      till += 1; // one sec later
      cond_.timed_wait(lock_, till);
#else
      int status;
      int r = waitpid(pid_->pid(), &status, WNOHANG);
      if (r == 0) {
        lock_.unlock();
        sleep(1);
        lock_.lock();
        continue;
      }
      if (r == -1) // Child lost?
        status = -1;
      else
        status = WEXITSTATUS(status);
      // Child exited
      lock_.unlock();
      child_handler(pid_->pid(), status << 8);
      lock_.lock();
#endif
    }
    lock_.unlock();
    return (!running_);
  }

Here is the call graph for this function:

Here is the caller graph for this function:

int Arc::Run::WriteStdin ( int  timeout,
const char *  buf,
int  size 
)

Write to stdin handle of running executable.

Parameter timeout specifies upper limit for which method will block in milliseconds. Negative means infinite. This method may be used while stdin is directed to string. But result is unpredictable. Returns number of written bytes.

Definition at line 504 of file Run_unix.cpp.

                                                            {
    if (stdin_ == -1)
      return -1;
    // TODO: do it through context for timeout
    pollfd fd;
    fd.fd = stdout_; fd.events = POLLOUT; fd.revents = 0;
    int err = poll(&fd, 1, timeout);
    if(err <= 0) return err;
    if(!(fd.revents & POLLOUT)) return -1;
    return write(stdin_, buf, size);
  }

Here is the caller graph for this function:


Friends And Related Function Documentation

friend class RunPump [friend]

Definition at line 17 of file Run.h.


Member Data Documentation

bool Arc::Run::abandoned_ [protected]

Definition at line 57 of file Run.h.

Glib::ArrayHandle<std::string> Arc::Run::argv_ [protected]

Definition at line 44 of file Run.h.

sigc::connection Arc::Run::child_conn_ [protected]

Definition at line 40 of file Run.h.

Glib::Cond Arc::Run::cond_ [protected]

Definition at line 60 of file Run.h.

void* Arc::Run::initializer_arg_ [protected]

Definition at line 46 of file Run.h.

void(* Arc::Run::initializer_func_)(void *) [protected]

Definition at line 45 of file Run.h.

void* Arc::Run::kicker_arg_ [protected]

Definition at line 48 of file Run.h.

void(* Arc::Run::kicker_func_)(void *) [protected]

Definition at line 47 of file Run.h.

Glib::Mutex Arc::Run::lock_ [protected]

Definition at line 59 of file Run.h.

Pid* Arc::Run::pid_ [protected]

Definition at line 42 of file Run.h.

int Arc::Run::result_ [protected]

Definition at line 58 of file Run.h.

bool Arc::Run::running_ [protected]

Definition at line 56 of file Run.h.

bool Arc::Run::started_ [protected]

Definition at line 55 of file Run.h.

int Arc::Run::stderr_ [protected]

Definition at line 26 of file Run.h.

sigc::connection Arc::Run::stderr_conn_ [protected]

Definition at line 38 of file Run.h.

bool Arc::Run::stderr_keep_ [protected]

Definition at line 34 of file Run.h.

std::string* Arc::Run::stderr_str_ [protected]

Definition at line 30 of file Run.h.

int Arc::Run::stdin_ [protected]

Definition at line 27 of file Run.h.

sigc::connection Arc::Run::stdin_conn_ [protected]

Definition at line 39 of file Run.h.

bool Arc::Run::stdin_keep_ [protected]

Definition at line 35 of file Run.h.

std::string* Arc::Run::stdin_str_ [protected]

Definition at line 31 of file Run.h.

int Arc::Run::stdout_ [protected]

Definition at line 25 of file Run.h.

sigc::connection Arc::Run::stdout_conn_ [protected]

Definition at line 37 of file Run.h.

bool Arc::Run::stdout_keep_ [protected]

Definition at line 33 of file Run.h.

std::string* Arc::Run::stdout_str_ [protected]

Definition at line 29 of file Run.h.

std::string Arc::Run::working_directory [protected]

Definition at line 23 of file Run.h.


The documentation for this class was generated from the following files: