1 #pragma once 2 3 #include <stdio.h> 4 5 #include <experimental/filesystem> 6 namespace phosphor 7 { 8 namespace user 9 { 10 11 namespace fs = std::experimental::filesystem; 12 13 /** @class File 14 * @brief Responsible for handling file pointer 15 * Needed by putspent(3) 16 */ 17 class File 18 { 19 private: 20 /** @brief handler for operating on file */ 21 FILE* fp = NULL; 22 23 /** @brief File name. Needed in the case where the temp 24 * needs to be removed 25 */ 26 const std::string& name; 27 28 /** @brief Should the file be removed at exit */ 29 bool removeOnExit = false; 30 31 public: 32 File() = delete; 33 File(const File&) = delete; 34 File& operator=(const File&) = delete; 35 File(File&&) = delete; 36 File& operator=(File&&) = delete; 37 38 /** @brief Opens file and uses it to do file operation 39 * 40 * @param[in] name - File name 41 * @param[in] mode - File open mode 42 * @param[in] removeOnExit - File to be removed at exit or no 43 */ 44 File(const std::string& name, const std::string& mode, 45 bool removeOnExit = false) : 46 name(name), 47 removeOnExit(removeOnExit) 48 { 49 fp = fopen(name.c_str(), mode.c_str()); 50 } 51 52 /** @brief Opens file using provided file descriptor 53 * 54 * @param[in] fd - File descriptor 55 * @param[in] name - File name 56 * @param[in] mode - File open mode 57 * @param[in] removeOnExit - File to be removed at exit or no 58 */ 59 File(int fd, const std::string& name, const std::string& mode, 60 bool removeOnExit = false) : 61 name(name), 62 removeOnExit(removeOnExit) 63 { 64 fp = fdopen(fd, mode.c_str()); 65 } 66 67 ~File() 68 { 69 if (fp) 70 { 71 fclose(fp); 72 } 73 74 // Needed for exception safety 75 if (removeOnExit && fs::exists(name)) 76 { 77 fs::remove(name); 78 } 79 } 80 81 auto operator()() 82 { 83 return fp; 84 } 85 }; 86 87 } // namespace user 88 } // namespace phosphor 89