/* * This source code is released into the public domain. */ #include #include #include #include #include "getenv.hh" #include "path.hh" using namespace std::literals; namespace lfjail { auto find_in_path(std::string const &file) -> std::optional { if (file.empty()) return {}; auto try_open = [](std::string const &path) -> std::optional { auto const ret = ::open(path.c_str(), O_EXEC); if (ret == -1) return {}; return fd(ret); }; // Absolute pathname skips the search. if (file[0] == '/') return try_open(file); auto path = getenv("PATH").value_or(_PATH_DEFPATH); for (auto &&dir : std::views::split(path, ':')) { // An empty $PATH element means cwd. auto sdir = std::string_view(dir); if (sdir.empty()) sdir = "."; auto const path = std::format("{}/{}", sdir, file); if (auto ret = try_open(path); ret) return ret; } return {}; } } // namespace lfjail