#ifndef IO_HH #define IO_HH #include "unique_fd.hh" #include #include class Buffer; class RoBuffer; namespace io { bool make_nonblocking(int fd); bool mkdirs(std::filesystem::path const& path, mode_t mode); bool mkdirs(int fd, std::filesystem::path const& path, mode_t mode); bool read_all(int fd, void* data, size_t size); bool write_all(int fd, void const* data, size_t size); bool seek_all(int fd, size_t bytes); enum class Return { OK, ERR, CLOSED, }; Return fill(int fd, Buffer* out, size_t buf_request_size = 1, size_t* bytes = nullptr); // Returns false in case of error. EAGAIN or EWOULDBLOCK are not errors. bool drain(RoBuffer* in, int fd, size_t* bytes = nullptr); enum class open_flags : unsigned { rdonly = 00, wronly = 01, rdwr = 02, create = 0100, excl = 0200, trunc = 01000, append = 02000, directory = 0200000, path = 010000000, }; unique_fd open(std::filesystem::path const& path, open_flags flags, std::filesystem::perms perms = std::filesystem::perms::none); unique_fd openat(int fd, std::filesystem::path const& path, open_flags flags, std::filesystem::perms perms = std::filesystem::perms::none); bool close(int fd); ssize_t pread(int fd, void *buf, size_t count, off_t offset); ssize_t read(int fd, void *buf, size_t count); ssize_t write(int fd, const void *buf, size_t count); enum class access_mode : unsigned { exists = 00, read = 01, write = 02, exec = 04, }; bool access(std::filesystem::path const& path, access_mode mode); bool unlinkat(int fd, std::filesystem::path const& path); bool fallocate(int fd, off_t offset, off_t len); constexpr open_flags operator&(open_flags a, open_flags b) noexcept { using utype = typename std::underlying_type::type; return static_cast(static_cast(a) & static_cast(b)); } constexpr open_flags operator|(open_flags a, open_flags b) noexcept { using utype = typename std::underlying_type::type; return static_cast(static_cast(a) | static_cast(b)); } constexpr open_flags operator^(open_flags a, open_flags b) noexcept { using utype = typename std::underlying_type::type; return static_cast(static_cast(a) ^ static_cast(b)); } constexpr open_flags operator~(open_flags a) noexcept { using utype = typename std::underlying_type::type; return static_cast(~static_cast(a)); } constexpr access_mode operator&(access_mode a, access_mode b) noexcept { using utype = typename std::underlying_type::type; return static_cast( static_cast(a) & static_cast(b)); } constexpr access_mode operator|(access_mode a, access_mode b) noexcept { using utype = typename std::underlying_type::type; return static_cast( static_cast(a) | static_cast(b)); } constexpr access_mode operator^(access_mode a, access_mode b) noexcept { using utype = typename std::underlying_type::type; return static_cast( static_cast(a) ^ static_cast(b)); } constexpr access_mode operator~(access_mode a) noexcept { using utype = typename std::underlying_type::type; return static_cast(~static_cast(a)); } } // namespace io #endif // IO_HH