39 const sigset_t *sigmask)
42 std::unique_ptr<ArgvWrapper> env_wrap;
45 auto fn = cmd.c_str();
46 auto av = argv_wrap.
c_argv();
47 auto ev = env_wrap ? env_wrap->c_argv() :
::environ;
51 const pid_t pid = ::fork();
53 const pid_t pid = (redir || sigmask) ? ::fork() : ::vfork();
61 ::pthread_sigmask(SIG_SETMASK, sigmask, 0);
67 else if (pid < pid_t(0))
81 if (::waitpid(pid, &status, 0) == pid)
83 if (WIFEXITED(status))
84 return WEXITSTATUS(status);
94 const sigset_t *sigmask)
105 return system_cmd(cmd, argv,
nullptr,
nullptr,
nullptr);
124 unsigned int redirect_pipe_flags,
125 const sigset_t *sigmask)
129 if (!inout.
in.empty())
148 :
argv(std::move(argv_arg))
160 virtual void execute(std::ostream &os)
override
165#ifdef OPENVPN_PROCESS_AVOID_PIPES
168 os <<
"Error: command failed to execute" << std::endl;
173 os <<
"Error: command failed to execute" << std::endl;
177 if (inout.
out.find(
"File exists") != std::string::npos)
178 throw Exception(
"Route already exists, new route will be ignored");
182 os <<
"Error: command called with empty argv" << std::endl;
char *const * c_argv() const noexcept
std::string to_string() const
void transact(InOut &inout)
Support deferred server-side state creation when client connects.
int system_cmd_post(const pid_t pid)
pid_t system_cmd_async(const std::string &cmd, const Argv &argv, const Environ *env, RedirectBase *redir, const sigset_t *sigmask)
int system_cmd(const std::string &cmd, const Argv &argv, RedirectBase *redir, const Environ *env, const sigset_t *sigmask)
virtual std::string to_string() const override
virtual void execute(std::ostream &os) override
virtual void redirect()=0