// This source code is released into the public domain. module; #include #include export module nihil.posix:open; import nihil.std; import nihil.error; import nihil.util; import :fd; namespace nihil { // Flags which can be passed to open(). struct open_flags_tag { }; export using open_flags = nihil::flagset; export inline constexpr auto open_none = open_flags(); // Basic flags, exactly one of these is required. export inline constexpr auto open_read = open_flags::mask(); export inline constexpr auto open_write = open_flags::mask(); export inline constexpr auto open_readwrite = open_flags::mask(); export inline constexpr auto open_search = open_flags::mask(); export inline constexpr auto open_exec = open_flags::mask(); // Modifiers export inline constexpr auto open_nonblock = open_flags::mask(); export inline constexpr auto open_append = open_flags::mask(); export inline constexpr auto open_create = open_flags::mask(); export inline constexpr auto open_truncate = open_flags::mask(); export inline constexpr auto open_exclusive = open_flags::mask(); export inline constexpr auto open_shared_lock = open_flags::mask(); export inline constexpr auto open_exclusive_lock = open_flags::mask(); export inline constexpr auto open_directory = open_flags::mask(); export inline constexpr auto open_nofollow = open_flags::mask(); export inline constexpr auto open_close_on_exec = open_flags::mask(); export inline constexpr auto open_resolve_beneath = open_flags::mask(); // FreeBSD #ifdef O_DIRECT export inline constexpr auto open_direct = open_flags::mask(); #endif #ifdef O_VERIFY export inline constexpr auto open_verify = open_flags::mask(); #endif #ifdef O_PATH export inline constexpr auto open_path = open_flags::mask(); #endif #ifdef O_EMPTY_PATH export inline constexpr auto open_empty_path = open_flags::mask(); #endif // macOS #ifdef O_NOFOLLOW_ANY export inline constexpr auto open_nofollow_any = open_flags::mask(); #endif #ifdef O_SYMLINK export inline constexpr auto open_symlink = open_flags::mask(); #endif #ifdef O_EVTONLY export inline constexpr auto open_eventonly = open_flags::mask(); #endif // Open the given file and return an fd for it. export [[nodiscard]] auto open(std::filesystem::path const &filename, open_flags flags, int mode = 0777) -> std::expected { auto fdno = ::open(filename.c_str(), flags.value(), mode); if (fdno != -1) return fd(fdno); return error(sys_error()); } // Like open(), but resolve relative to an open file descriptor, which must refer to a directory. export [[nodiscard]] auto openat(fd &where, std::filesystem::path const &filename, open_flags flags, int mode = 0777) -> std::expected { auto fdno = ::openat(where.get(), filename.c_str(), flags.value(), mode); if (fdno != -1) return fd(fdno); return error(sys_error()); } } // namespace nihil