16e36587aSZane Shelley #pragma once 26e36587aSZane Shelley 36e36587aSZane Shelley #include <unistd.h> // for close() 46e36587aSZane Shelley 56e36587aSZane Shelley namespace util 66e36587aSZane Shelley { 76e36587aSZane Shelley 86e36587aSZane Shelley /** 96e36587aSZane Shelley * @class FileDescriptor 106e36587aSZane Shelley * 116e36587aSZane Shelley * This class manages an open file descriptor. 126e36587aSZane Shelley * 136e36587aSZane Shelley * The file descriptor can be closed by calling close(). Otherwise it will be 146e36587aSZane Shelley * closed by the destructor. 156e36587aSZane Shelley * 166e36587aSZane Shelley * FileDescriptor objects cannot be copied, but they can be moved. This enables 176e36587aSZane Shelley * them to be stored in containers like std::vector. 186e36587aSZane Shelley */ 196e36587aSZane Shelley class FileDescriptor 206e36587aSZane Shelley { 216e36587aSZane Shelley public: 226e36587aSZane Shelley FileDescriptor() = default; 236e36587aSZane Shelley FileDescriptor(const FileDescriptor&) = delete; 246e36587aSZane Shelley FileDescriptor& operator=(const FileDescriptor&) = delete; 256e36587aSZane Shelley 266e36587aSZane Shelley /** 276e36587aSZane Shelley * Constructor. 286e36587aSZane Shelley * 296e36587aSZane Shelley * @param[in] fd - File descriptor 306e36587aSZane Shelley */ FileDescriptor(int fd)316e36587aSZane Shelley explicit FileDescriptor(int fd) : fd(fd) {} 326e36587aSZane Shelley 336e36587aSZane Shelley /** 346e36587aSZane Shelley * Move constructor. 356e36587aSZane Shelley * 366e36587aSZane Shelley * Transfers ownership of a file descriptor. 376e36587aSZane Shelley * 386e36587aSZane Shelley * @param other - FileDescriptor object being moved 396e36587aSZane Shelley */ FileDescriptor(FileDescriptor && other)406e36587aSZane Shelley FileDescriptor(FileDescriptor&& other) : fd(other.fd) 416e36587aSZane Shelley { 426e36587aSZane Shelley other.fd = -1; 436e36587aSZane Shelley } 446e36587aSZane Shelley 456e36587aSZane Shelley /** 466e36587aSZane Shelley * Move assignment operator. 476e36587aSZane Shelley * 486e36587aSZane Shelley * Closes the file descriptor owned by this object, if any. Then transfers 496e36587aSZane Shelley * ownership of the file descriptor owned by the other object. 506e36587aSZane Shelley * 516e36587aSZane Shelley * @param other - FileDescriptor object being moved 526e36587aSZane Shelley */ operator =(FileDescriptor && other)536e36587aSZane Shelley FileDescriptor& operator=(FileDescriptor&& other) 546e36587aSZane Shelley { 556e36587aSZane Shelley // Verify not assigning object to itself (a = std::move(a)) 566e36587aSZane Shelley if (this != &other) 576e36587aSZane Shelley { 586e36587aSZane Shelley set(other.fd); 596e36587aSZane Shelley other.fd = -1; 606e36587aSZane Shelley } 616e36587aSZane Shelley return *this; 626e36587aSZane Shelley } 636e36587aSZane Shelley 646e36587aSZane Shelley /** 656e36587aSZane Shelley * Destructor. 666e36587aSZane Shelley * 676e36587aSZane Shelley * Closes the file descriptor if necessary. 686e36587aSZane Shelley */ ~FileDescriptor()696e36587aSZane Shelley ~FileDescriptor() 706e36587aSZane Shelley { 716e36587aSZane Shelley close(); 726e36587aSZane Shelley } 736e36587aSZane Shelley 746e36587aSZane Shelley /** 756e36587aSZane Shelley * Returns the file descriptor. 766e36587aSZane Shelley * 776e36587aSZane Shelley * @return File descriptor. Returns -1 if this object does not contain an 786e36587aSZane Shelley * open file descriptor. 796e36587aSZane Shelley */ operator ()() const80*584f179eSZane Shelley int operator()() const 816e36587aSZane Shelley { 826e36587aSZane Shelley return fd; 836e36587aSZane Shelley } 846e36587aSZane Shelley 856e36587aSZane Shelley /** 866e36587aSZane Shelley * Returns whether this object contains an open file descriptor. 876e36587aSZane Shelley * 886e36587aSZane Shelley * @return true if object contains an open file descriptor, false otherwise. 896e36587aSZane Shelley */ operator bool() const906e36587aSZane Shelley operator bool() const 916e36587aSZane Shelley { 926e36587aSZane Shelley return fd != -1; 936e36587aSZane Shelley } 946e36587aSZane Shelley 956e36587aSZane Shelley /** 966e36587aSZane Shelley * Closes the file descriptor. 976e36587aSZane Shelley * 986e36587aSZane Shelley * Does nothing if the file descriptor was not set or was already closed. 996e36587aSZane Shelley * 1006e36587aSZane Shelley * @return 0 if descriptor was successfully closed. Returns -1 if an error 1016e36587aSZane Shelley * occurred; errno will be set appropriately. 1026e36587aSZane Shelley */ close()1036e36587aSZane Shelley int close() 1046e36587aSZane Shelley { 1056e36587aSZane Shelley int rc = 0; 1066e36587aSZane Shelley if (fd >= 0) 1076e36587aSZane Shelley { 1086e36587aSZane Shelley rc = ::close(fd); 1096e36587aSZane Shelley fd = -1; 1106e36587aSZane Shelley } 1116e36587aSZane Shelley return rc; 1126e36587aSZane Shelley } 1136e36587aSZane Shelley 1146e36587aSZane Shelley /** 1156e36587aSZane Shelley * Sets the file descriptor. 1166e36587aSZane Shelley * 1176e36587aSZane Shelley * Closes the previous file descriptor if necessary. 1186e36587aSZane Shelley * 1196e36587aSZane Shelley * @param[in] descriptor - File descriptor 1206e36587aSZane Shelley */ set(int descriptor)1216e36587aSZane Shelley void set(int descriptor) 1226e36587aSZane Shelley { 1236e36587aSZane Shelley close(); 1246e36587aSZane Shelley fd = descriptor; 1256e36587aSZane Shelley } 1266e36587aSZane Shelley 1276e36587aSZane Shelley private: 1286e36587aSZane Shelley /** 1296e36587aSZane Shelley * File descriptor. 1306e36587aSZane Shelley */ 1316e36587aSZane Shelley int fd = -1; 1326e36587aSZane Shelley }; 1336e36587aSZane Shelley 1346e36587aSZane Shelley } // namespace util 135