/* * This source code is released into the public domain. */ /* * Exec providers for spawn(). */ #ifndef LFJAIL_EXEC_HH #define LFJAIL_EXEC_HH #include #include "argv.hh" #include "exec_error.hh" #include "fd.hh" #include "guard.hh" #include "path.hh" namespace lfjail::exec { /* * A concept to mark spawn executors. */ struct exec_tag{}; template concept executor = requires (T e) { std::same_as; { e.exec() }; }; /* * 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. * * TODO: Should have a way to pass the environment (envp). */ struct fexecv final { using tag = exec_tag; fexecv(fd &&execfd, argv &&args) noexcept; [[noreturn]] auto exec(this fexecv &self) noexcept -> void; // 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 _execfd; argv _args; }; static_assert(executor); /* * execv: equivalent to fexecv(), except the command is passed as * a pathname instead of a file descriptor. Does not search $PATH. */ auto execv(std::string const &path, argv &&argv) -> fexecv; /* * execvp: equivalent to fexecv(), except the command is passed as * a filename instead of a file descriptor. If the filename is not * an absolute path, it will be searched for in $PATH. */ auto execvp(std::string const &file, argv &&argv) -> fexecv; /* * execl: equivalent to execv, except the arguments are passed as a * variadic pack of string-like objects. */ auto execl(std::string const &path, auto &&...args) { return execv(path, argv::from_args({std::string_view(args)...})); } /* * execlp: equivalent to execvp, except the arguments are passed as a * variadic pack of string-like objects. */ auto execlp(std::string const &file, auto &&...args) { return execvp(file, argv::from_args({std::string_view(args)...})); } /* * shell: run the process by invoking /bin/sh -c with the single argument, * equivalent to system(3). */ auto shell(std::string const &command) -> fexecv; } // namespace lfjail #endif // LFJAIL_EXEC_HH