1 /**
2  * Copyright © 2020 IBM Corporation
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 #pragma once
17 
18 #include <filesystem>
19 #include <utility>
20 
21 namespace phosphor::power::util
22 {
23 
24 /**
25  * @class TemporaryFile
26  *
27  * A temporary file in the file system.
28  *
29  * The temporary file is created by the constructor.  The absolute path to the
30  * file can be obtained using getPath().
31  *
32  * The temporary file can be deleted by calling remove().  Otherwise the file
33  * will be deleted by the destructor.
34  *
35  * TemporaryFile objects cannot be copied, but they can be moved.  This enables
36  * them to be stored in containers like std::vector.
37  */
38 class TemporaryFile
39 {
40   public:
41     // Specify which compiler-generated methods we want
42     TemporaryFile(const TemporaryFile&) = delete;
43     TemporaryFile& operator=(const TemporaryFile&) = delete;
44 
45     /**
46      * Constructor.
47      *
48      * Creates a temporary file in the temporary directory (normally /tmp).
49      *
50      * Throws an exception if the file cannot be created.
51      */
52     TemporaryFile();
53 
54     /**
55      * Move constructor.
56      *
57      * Transfers ownership of a temporary file.
58      *
59      * @param file TemporaryFile object being moved
60      */
61     TemporaryFile(TemporaryFile&& file) : path{std::move(file.path)}
62     {
63         // Clear path in other object; after move path is in unspecified state
64         file.path.clear();
65     }
66 
67     /**
68      * Move assignment operator.
69      *
70      * Deletes the temporary file owned by this object.  Then transfers
71      * ownership of the temporary file owned by the other object.
72      *
73      * Throws an exception if an error occurs during the deletion.
74      *
75      * @param file TemporaryFile object being moved
76      */
77     TemporaryFile& operator=(TemporaryFile&& file);
78 
79     /**
80      * Destructor.
81      *
82      * Deletes the temporary file if necessary.
83      */
84     ~TemporaryFile()
85     {
86         try
87         {
88             remove();
89         }
90         catch (...)
91         {
92             // Destructors should not throw exceptions
93         }
94     }
95 
96     /**
97      * Deletes the temporary file.
98      *
99      * Does nothing if the file has already been deleted.
100      *
101      * Throws an exception if an error occurs during the deletion.
102      */
103     void remove();
104 
105     /**
106      * Returns the absolute path to the temporary file.
107      *
108      * Returns an empty path if the file has been deleted.
109      *
110      * @return temporary file path
111      */
112     const std::filesystem::path& getPath() const
113     {
114         return path;
115     }
116 
117   private:
118     /**
119      * Absolute path to the temporary file.
120      *
121      * Empty when file has been deleted.
122      */
123     std::filesystem::path path{};
124 };
125 
126 } // namespace phosphor::power::util
127