| Home | Libraries | People | FAQ | More

## 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. */.
      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
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 send to the father process interally

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

    child c(pid, exit_code);

    unspecified();//here, we read the 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 a 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
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
   This is the required way to handle errors in initializers.

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

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