blob: 4b98aeaaa0e0d1b0d4a64f13118f71b4f929df77 [file] [log] [blame]
Shawn McCarney9462e062020-09-15 14:39:17 -05001#pragma once
2
3#include <unistd.h> // for close()
4
5namespace phosphor::power::util
6{
7
8/**
9 * @class FileDescriptor
10 *
11 * This class manages an open file descriptor.
12 *
13 * The file descriptor can be closed by calling close(). Otherwise it will be
14 * closed by the destructor.
15 *
16 * FileDescriptor objects cannot be copied, but they can be moved. This enables
17 * them to be stored in containers like std::vector.
18 */
19class FileDescriptor
20{
21 public:
22 FileDescriptor() = default;
23 FileDescriptor(const FileDescriptor&) = delete;
24 FileDescriptor& operator=(const FileDescriptor&) = delete;
25
26 /**
27 * Constructor.
28 *
29 * @param[in] fd - File descriptor
30 */
31 FileDescriptor(int fd) : fd(fd)
Adriana Kobylak0c9a33d2021-09-13 18:05:09 +000032 {}
Shawn McCarney9462e062020-09-15 14:39:17 -050033
34 /**
35 * Move constructor.
36 *
37 * Transfers ownership of a file descriptor.
38 *
39 * @param other - FileDescriptor object being moved
40 */
41 FileDescriptor(FileDescriptor&& other) : fd(other.fd)
42 {
43 other.fd = -1;
44 }
45
46 /**
47 * Move assignment operator.
48 *
49 * Closes the file descriptor owned by this object, if any. Then transfers
50 * ownership of the file descriptor owned by the other object.
51 *
52 * @param other - FileDescriptor object being moved
53 */
54 FileDescriptor& operator=(FileDescriptor&& other)
55 {
56 // Verify not assigning object to itself (a = std::move(a))
57 if (this != &other)
58 {
59 set(other.fd);
60 other.fd = -1;
61 }
62 return *this;
63 }
64
65 /**
66 * Destructor.
67 *
68 * Closes the file descriptor if necessary.
69 */
70 ~FileDescriptor()
71 {
72 close();
73 }
74
75 /**
76 * Returns the file descriptor.
77 *
78 * @return File descriptor. Returns -1 if this object does not contain an
79 * open file descriptor.
80 */
81 int operator()()
82 {
83 return fd;
84 }
85
86 /**
87 * Returns whether this object contains an open file descriptor.
88 *
89 * @return true if object contains an open file descriptor, false otherwise.
90 */
91 operator bool() const
92 {
93 return fd != -1;
94 }
95
96 /**
97 * Closes the file descriptor.
98 *
99 * Does nothing if the file descriptor was not set or was already closed.
100 *
101 * @return 0 if descriptor was successfully closed. Returns -1 if an error
102 * occurred; errno will be set appropriately.
103 */
104 int close()
105 {
106 int rc = 0;
107 if (fd >= 0)
108 {
109 rc = ::close(fd);
110 fd = -1;
111 }
112 return rc;
113 }
114
115 /**
116 * Sets the file descriptor.
117 *
118 * Closes the previous file descriptor if necessary.
119 *
120 * @param[in] descriptor - File descriptor
121 */
122 void set(int descriptor)
123 {
124 close();
125 fd = descriptor;
126 }
127
128 private:
129 /**
130 * File descriptor.
131 */
132 int fd = -1;
133};
134
135} // namespace phosphor::power::util