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