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;