Boost C++ Libraries

...one of the most highly regarded and expertly designed C++ library projects in the world. Herb Sutter and Andrei Alexandrescu, C++ Coding Standards

PrevUpHomeNext

Struct template posix_executor

boost::process::extend::posix_executor — The posix executor type.

Synopsis

// In header: <boost/process/extend.hpp>

template<typename Sequence> 
struct posix_executor {

  // public member functions
  const std::error_code & error() const;
  void set_error(const std::error_code &, const std::string &);
  void set_error(const std::error_code &, const char *);

  // public data members
  Sequence & seq;  // A reference to the actual initializer-sequence. 
  const char * exe;  // A pointer to the name of the executable. 
  char *const  * cmd_line;  // A pointer to the argument-vector. 
  char ** env;  // A pointer to the environment variables, as default it is set to environ
  pid_t pid;  // The pid of the process - it will be -1 before invoking fork, and after forking either 0 for the new process or a positive value if in the current process. *<zwj></zwj>/. 
  std::shared_ptr< std::atomic< int > > exit_status;  // This shared-pointer holds the exit code. It's done this way, so it can be shared between an asio::io_context and child. 
};

Description

This type represents the posix executor and can be used for overloading in a custom handler.

[Note] Note

It is an alias for the implementation on posix, and a forward-declaration on windows.

As information for extension development, here is the structure of the process launching (in pseudo-code and uml)

for (auto & s : seq)
    s.on_setup(*this);

if (error())
{
    for (auto & s : seq)
       s.on_error(*this, error());
    return child();
}

pid = fork()
on_setup(*this);

if (pid == -1) //fork error 
{
    set_error(get_last_error());
    for (auto & s : seq)
        s.on_fork_error(*this, error());
    for (auto & s : seq)
        s.on_error(*this, error());
    return child()
}
else if (pid == 0) //child process
{
    for (auto & s : seq)
        s.on_exec_setup(*this);
    execve(exe, cmd_line, env);
    auto ec = get_last_error();
    for (auto & s : seq)
        s.on_exec_error(*this);

    unspecified();//here the error is sent to the father process internally

    std::exit(EXIT_FAILURE);
    return child(); //for C++ compliance
}

child c(pid, exit_code);

unspecified();//here, we read the error from the child process

if (error())
    for (auto & s : seq)
        s.on_error(*this, error());
else
    for (auto & s : seq)
        s.on_success(*this);

//now we check again, because an on_success handler might've errored.
if (error())
{
    for (auto & s : seq)
        s.on_error(*this, error());
    return child();
}
else
    return c;

The sequence if when no error occurs.

The sequence if the execution fails.

The sequence if the fork fails.

[Note] Note

Error handling if execve fails is done through a pipe, unless ignore_error is used.

Template Parameters

  1. typename Sequence

    The used initializer-sequence, it is fulfills the boost.fusion sequence concept.

posix_executor public member functions

  1. const std::error_code & error() const;
    This function returns a const reference to the error state of the executor.
  2. void set_error(const std::error_code & ec, const std::string & msg);

    This function can be used to report an error to the executor. This will be handled according to the configuration of the executor, i.e. it might throw an exception.

    [Note] Note

    This is the required way to handle errors in initializers.

    This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

  3. void set_error(const std::error_code & ec, const char * msg);

PrevUpHomeNext