19462e066SShawn McCarney #pragma once 29462e066SShawn McCarney 39462e066SShawn McCarney #include <unistd.h> // for close() 49462e066SShawn McCarney 59462e066SShawn McCarney namespace phosphor::power::util 69462e066SShawn McCarney { 79462e066SShawn McCarney 89462e066SShawn McCarney /** 99462e066SShawn McCarney * @class FileDescriptor 109462e066SShawn McCarney * 119462e066SShawn McCarney * This class manages an open file descriptor. 129462e066SShawn McCarney * 139462e066SShawn McCarney * The file descriptor can be closed by calling close(). Otherwise it will be 149462e066SShawn McCarney * closed by the destructor. 159462e066SShawn McCarney * 169462e066SShawn McCarney * FileDescriptor objects cannot be copied, but they can be moved. This enables 179462e066SShawn McCarney * them to be stored in containers like std::vector. 189462e066SShawn McCarney */ 199462e066SShawn McCarney class FileDescriptor 209462e066SShawn McCarney { 219462e066SShawn McCarney public: 229462e066SShawn McCarney FileDescriptor() = default; 239462e066SShawn McCarney FileDescriptor(const FileDescriptor&) = delete; 249462e066SShawn McCarney FileDescriptor& operator=(const FileDescriptor&) = delete; 259462e066SShawn McCarney 269462e066SShawn McCarney /** 279462e066SShawn McCarney * Constructor. 289462e066SShawn McCarney * 299462e066SShawn McCarney * @param[in] fd - File descriptor 309462e066SShawn McCarney */ FileDescriptor(int fd)31*48781aefSPatrick Williams FileDescriptor(int fd) : fd(fd) {} 329462e066SShawn McCarney 339462e066SShawn McCarney /** 349462e066SShawn McCarney * Move constructor. 359462e066SShawn McCarney * 369462e066SShawn McCarney * Transfers ownership of a file descriptor. 379462e066SShawn McCarney * 389462e066SShawn McCarney * @param other - FileDescriptor object being moved 399462e066SShawn McCarney */ FileDescriptor(FileDescriptor && other)409462e066SShawn McCarney FileDescriptor(FileDescriptor&& other) : fd(other.fd) 419462e066SShawn McCarney { 429462e066SShawn McCarney other.fd = -1; 439462e066SShawn McCarney } 449462e066SShawn McCarney 459462e066SShawn McCarney /** 469462e066SShawn McCarney * Move assignment operator. 479462e066SShawn McCarney * 489462e066SShawn McCarney * Closes the file descriptor owned by this object, if any. Then transfers 499462e066SShawn McCarney * ownership of the file descriptor owned by the other object. 509462e066SShawn McCarney * 519462e066SShawn McCarney * @param other - FileDescriptor object being moved 529462e066SShawn McCarney */ operator =(FileDescriptor && other)539462e066SShawn McCarney FileDescriptor& operator=(FileDescriptor&& other) 549462e066SShawn McCarney { 559462e066SShawn McCarney // Verify not assigning object to itself (a = std::move(a)) 569462e066SShawn McCarney if (this != &other) 579462e066SShawn McCarney { 589462e066SShawn McCarney set(other.fd); 599462e066SShawn McCarney other.fd = -1; 609462e066SShawn McCarney } 619462e066SShawn McCarney return *this; 629462e066SShawn McCarney } 639462e066SShawn McCarney 649462e066SShawn McCarney /** 659462e066SShawn McCarney * Destructor. 669462e066SShawn McCarney * 679462e066SShawn McCarney * Closes the file descriptor if necessary. 689462e066SShawn McCarney */ ~FileDescriptor()699462e066SShawn McCarney ~FileDescriptor() 709462e066SShawn McCarney { 719462e066SShawn McCarney close(); 729462e066SShawn McCarney } 739462e066SShawn McCarney 749462e066SShawn McCarney /** 759462e066SShawn McCarney * Returns the file descriptor. 769462e066SShawn McCarney * 779462e066SShawn McCarney * @return File descriptor. Returns -1 if this object does not contain an 789462e066SShawn McCarney * open file descriptor. 799462e066SShawn McCarney */ operator ()()809462e066SShawn McCarney int operator()() 819462e066SShawn McCarney { 829462e066SShawn McCarney return fd; 839462e066SShawn McCarney } 849462e066SShawn McCarney 859462e066SShawn McCarney /** 869462e066SShawn McCarney * Returns whether this object contains an open file descriptor. 879462e066SShawn McCarney * 889462e066SShawn McCarney * @return true if object contains an open file descriptor, false otherwise. 899462e066SShawn McCarney */ operator bool() const909462e066SShawn McCarney operator bool() const 919462e066SShawn McCarney { 929462e066SShawn McCarney return fd != -1; 939462e066SShawn McCarney } 949462e066SShawn McCarney 959462e066SShawn McCarney /** 969462e066SShawn McCarney * Closes the file descriptor. 979462e066SShawn McCarney * 989462e066SShawn McCarney * Does nothing if the file descriptor was not set or was already closed. 999462e066SShawn McCarney * 1009462e066SShawn McCarney * @return 0 if descriptor was successfully closed. Returns -1 if an error 1019462e066SShawn McCarney * occurred; errno will be set appropriately. 1029462e066SShawn McCarney */ close()1039462e066SShawn McCarney int close() 1049462e066SShawn McCarney { 1059462e066SShawn McCarney int rc = 0; 1069462e066SShawn McCarney if (fd >= 0) 1079462e066SShawn McCarney { 1089462e066SShawn McCarney rc = ::close(fd); 1099462e066SShawn McCarney fd = -1; 1109462e066SShawn McCarney } 1119462e066SShawn McCarney return rc; 1129462e066SShawn McCarney } 1139462e066SShawn McCarney 1149462e066SShawn McCarney /** 1159462e066SShawn McCarney * Sets the file descriptor. 1169462e066SShawn McCarney * 1179462e066SShawn McCarney * Closes the previous file descriptor if necessary. 1189462e066SShawn McCarney * 1199462e066SShawn McCarney * @param[in] descriptor - File descriptor 1209462e066SShawn McCarney */ set(int descriptor)1219462e066SShawn McCarney void set(int descriptor) 1229462e066SShawn McCarney { 1239462e066SShawn McCarney close(); 1249462e066SShawn McCarney fd = descriptor; 1259462e066SShawn McCarney } 1269462e066SShawn McCarney 1279462e066SShawn McCarney private: 1289462e066SShawn McCarney /** 1299462e066SShawn McCarney * File descriptor. 1309462e066SShawn McCarney */ 1319462e066SShawn McCarney int fd = -1; 1329462e066SShawn McCarney }; 1339462e066SShawn McCarney 1349462e066SShawn McCarney } // namespace phosphor::power::util 135