-
Notifications
You must be signed in to change notification settings - Fork 10
/
file_descriptor.hpp
134 lines (121 loc) · 2.84 KB
/
file_descriptor.hpp
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
125
126
127
128
129
130
131
132
133
134
#pragma once
#include <unistd.h> // for close()
namespace phosphor::power::util
{
/**
* @class FileDescriptor
*
* This class manages an open file descriptor.
*
* The file descriptor can be closed by calling close(). Otherwise it will be
* closed by the destructor.
*
* FileDescriptor objects cannot be copied, but they can be moved. This enables
* them to be stored in containers like std::vector.
*/
class FileDescriptor
{
public:
FileDescriptor() = default;
FileDescriptor(const FileDescriptor&) = delete;
FileDescriptor& operator=(const FileDescriptor&) = delete;
/**
* Constructor.
*
* @param[in] fd - File descriptor
*/
FileDescriptor(int fd) : fd(fd) {}
/**
* Move constructor.
*
* Transfers ownership of a file descriptor.
*
* @param other - FileDescriptor object being moved
*/
FileDescriptor(FileDescriptor&& other) : fd(other.fd)
{
other.fd = -1;
}
/**
* Move assignment operator.
*
* Closes the file descriptor owned by this object, if any. Then transfers
* ownership of the file descriptor owned by the other object.
*
* @param other - FileDescriptor object being moved
*/
FileDescriptor& operator=(FileDescriptor&& other)
{
// Verify not assigning object to itself (a = std::move(a))
if (this != &other)
{
set(other.fd);
other.fd = -1;
}
return *this;
}
/**
* Destructor.
*
* Closes the file descriptor if necessary.
*/
~FileDescriptor()
{
close();
}
/**
* Returns the file descriptor.
*
* @return File descriptor. Returns -1 if this object does not contain an
* open file descriptor.
*/
int operator()()
{
return fd;
}
/**
* Returns whether this object contains an open file descriptor.
*
* @return true if object contains an open file descriptor, false otherwise.
*/
operator bool() const
{
return fd != -1;
}
/**
* Closes the file descriptor.
*
* Does nothing if the file descriptor was not set or was already closed.
*
* @return 0 if descriptor was successfully closed. Returns -1 if an error
* occurred; errno will be set appropriately.
*/
int close()
{
int rc = 0;
if (fd >= 0)
{
rc = ::close(fd);
fd = -1;
}
return rc;
}
/**
* Sets the file descriptor.
*
* Closes the previous file descriptor if necessary.
*
* @param[in] descriptor - File descriptor
*/
void set(int descriptor)
{
close();
fd = descriptor;
}
private:
/**
* File descriptor.
*/
int fd = -1;
};
} // namespace phosphor::power::util