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