summaryrefslogtreecommitdiff
path: root/src/io.hh
blob: f13b51bbbfb531dadcd2dbb8a4a03daad3e0e3a0 (plain)
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