1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
|
#ifndef IO_HH
#define IO_HH
#include "unique_fd.hh"
#include <filesystem>
#include <stdint.h>
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<open_flags>::type;
return static_cast<open_flags>(static_cast<utype>(a) & static_cast<utype>(b));
}
constexpr open_flags operator|(open_flags a, open_flags b) noexcept {
using utype = typename std::underlying_type<open_flags>::type;
return static_cast<open_flags>(static_cast<utype>(a) | static_cast<utype>(b));
}
constexpr open_flags operator^(open_flags a, open_flags b) noexcept {
using utype = typename std::underlying_type<open_flags>::type;
return static_cast<open_flags>(static_cast<utype>(a) ^ static_cast<utype>(b));
}
constexpr open_flags operator~(open_flags a) noexcept {
using utype = typename std::underlying_type<open_flags>::type;
return static_cast<open_flags>(~static_cast<utype>(a));
}
constexpr access_mode operator&(access_mode a, access_mode b) noexcept {
using utype = typename std::underlying_type<access_mode>::type;
return static_cast<access_mode>(
static_cast<utype>(a) & static_cast<utype>(b));
}
constexpr access_mode operator|(access_mode a, access_mode b) noexcept {
using utype = typename std::underlying_type<access_mode>::type;
return static_cast<access_mode>(
static_cast<utype>(a) | static_cast<utype>(b));
}
constexpr access_mode operator^(access_mode a, access_mode b) noexcept {
using utype = typename std::underlying_type<access_mode>::type;
return static_cast<access_mode>(
static_cast<utype>(a) ^ static_cast<utype>(b));
}
constexpr access_mode operator~(access_mode a) noexcept {
using utype = typename std::underlying_type<access_mode>::type;
return static_cast<access_mode>(~static_cast<utype>(a));
}
} // namespace io
#endif // IO_HH
|