blob: 7929aa6835d0803cc54e6663540ff1cacfe51a01 [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)
32 {
33 }
34
35 /**
36 * Move constructor.
37 *
38 * Transfers ownership of a file descriptor.
39 *
40 * @param other - FileDescriptor object being moved
41 */
42 FileDescriptor(FileDescriptor&& other) : fd(other.fd)
43 {
44 other.fd = -1;
45 }
46
47 /**
48 * Move assignment operator.
49 *
50 * Closes the file descriptor owned by this object, if any. Then transfers
51 * ownership of the file descriptor owned by the other object.
52 *
53 * @param other - FileDescriptor object being moved
54 */
55 FileDescriptor& operator=(FileDescriptor&& other)
56 {
57 // Verify not assigning object to itself (a = std::move(a))
58 if (this != &other)
59 {
60 set(other.fd);
61 other.fd = -1;
62 }
63 return *this;
64 }
65
66 /**
67 * Destructor.
68 *
69 * Closes the file descriptor if necessary.
70 */
71 ~FileDescriptor()
72 {
73 close();
74 }
75
76 /**
77 * Returns the file descriptor.
78 *
79 * @return File descriptor. Returns -1 if this object does not contain an
80 * open file descriptor.
81 */
82 int operator()()
83 {
84 return fd;
85 }
86
87 /**
88 * Returns whether this object contains an open file descriptor.
89 *
90 * @return true if object contains an open file descriptor, false otherwise.
91 */
92 operator bool() const
93 {
94 return fd != -1;
95 }
96
97 /**
98 * Closes the file descriptor.
99 *
100 * Does nothing if the file descriptor was not set or was already closed.
101 *
102 * @return 0 if descriptor was successfully closed. Returns -1 if an error
103 * occurred; errno will be set appropriately.
104 */
105 int close()
106 {
107 int rc = 0;
108 if (fd >= 0)
109 {
110 rc = ::close(fd);
111 fd = -1;
112 }
113 return rc;
114 }
115
116 /**
117 * Sets the file descriptor.
118 *
119 * Closes the previous file descriptor if necessary.
120 *
121 * @param[in] descriptor - File descriptor
122 */
123 void set(int descriptor)
124 {
125 close();
126 fd = descriptor;
127 }
128
129 private:
130 /**
131 * File descriptor.
132 */
133 int fd = -1;
134};
135
136} // namespace phosphor::power::util