summaryrefslogtreecommitdiff
path: root/src/io.hh
blob: 3bfccec8fdbe40cb3a9856aedcd7331ea09c1e8b (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
114
115
116
117
118
119
120
121
122
123
124
// -*- mode: c++; c-basic-offset: 2; -*-

#ifndef IO_HH
#define IO_HH

#include <sys/types.h>

namespace io {

ssize_t read(int fd, void* buf, size_t max);
ssize_t write(int fd, void const* buf, size_t max);

bool read_all(int fd, void* buf, size_t size);
bool write_all(int fd, void const* buf, size_t size);

class auto_fd {
public:
  auto_fd()
    : fd_(-1) {
  }
  explicit auto_fd(int fd)
    : fd_(fd) {
  }
  auto_fd(auto_fd&& fd)
    : fd_(fd.fd_) {
    fd.fd_ = -1;
  }
  auto_fd(auto_fd const&) = delete;
  ~auto_fd() {
    reset();
  }

  auto_fd& operator=(auto_fd&& fd) {
    reset(fd.release());
    return *this;
  }
  auto_fd& operator=(auto_fd&) = delete;

  int get() const {
    return fd_;
  }

  explicit operator bool() const {
    return fd_ >= 0;
  }

  int release() {
    auto ret = fd_;
    fd_ = -1;
    return ret;
  }

  bool reset();

  bool reset(int fd) {
    auto ret = reset();
    fd_ = fd;
    return ret;
  }

  void swap(auto_fd& fd) {
    auto tmp = fd_;
    fd_ = fd.fd_;
    fd.fd_ = tmp;
  }
private:
  int fd_;
};

class auto_pipe {
public:
  auto_pipe()
    : read_(-1), write_(-1) {
  }
  auto_pipe(auto_pipe&& pipe)
    : read_(pipe.read_), write_(pipe.write_) {
    pipe.read_ = -1;
    pipe.write_ = -1;
  }
  auto_pipe(auto_pipe const&) = delete;
  ~auto_pipe() {
    reset();
  }

  auto_pipe& operator=(auto_pipe&& pipe) {
    reset();
    read_ = pipe.read_;
    write_ = pipe.write_;
    pipe.read_ = -1;
    pipe.write_ = -1;
    return *this;
  }
  auto_pipe& operator=(auto_pipe&) = delete;

  int read() const {
    return read_;
  }
  int write() const {
    return write_;
  }

  explicit operator bool() const {
    return read_ >= 0 /* && write_ >= 0 */;
  }

  bool open();

  void reset();

  void swap(auto_pipe& pipe) {
    auto r = read_;
    auto w = write_;
    read_ = pipe.read_;
    write_ = pipe.write_;
    pipe.read_ = r;
    pipe.write_ = w;
  }
private:
  int read_, write_;
};

}  // namespace io

#endif  // IO_HH