// This source code is released into the public domain. module; #include #include #include "nihil.hh" export module nihil.posix:fexecv; import nihil.error; import :argv; import :executor; import :fd; namespace nihil { #ifdef NIHIL_HAVE_FEXECVE /* * fexecv: use a file descriptor and an argument vector to call ::fexecve(). * This is the lowest-level executor which all others are implemented * in terms of (if it's available). * * TODO: Should have a way to pass the environment (envp). */ export struct fexecv final { using tag = exec_tag; fexecv(fd &&execfd, argv &&args) noexcept : m_execfd(std::move(execfd)) , m_args(std::move(args)) { } [[nodiscard]] auto exec(this fexecv &self) -> std::expected { ::fexecve(self.m_execfd.get(), self.m_args.data(), environ); return std::unexpected(error("fexecve failed", error(std::errc(errno)))); } // Movable fexecv(fexecv &&) noexcept = default; auto operator=(this fexecv &, fexecv &&) noexcept -> fexecv & = default; // Not copyable (because we hold the open fd object) fexecv(fexecv const &) = delete; auto operator=(this fexecv &, fexecv const &) -> fexecv & = delete; private: fd m_execfd; argv m_args; }; #endif // NIHIL_HAVE_FEXECVE } // namespace nihil