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