1 /**
2  * Copyright © 2024 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 TemporarySubDirectory
26  *
27  * A temporary subdirectory in the file system.
28  *
29  * This class does NOT represent the system temporary directory (such as /tmp).
30  * It represents a temporary subdirectory below that directory.
31  *
32  * The temporary subdirectory is created by the constructor.  The absolute path
33  * to the subdirectory can be obtained using getPath().
34  *
35  * The temporary subdirectory can be deleted by calling remove().  Otherwise the
36  * subdirectory will be deleted by the destructor.
37  *
38  * TemporarySubDirectory objects cannot be copied, but they can be moved.  This
39  * enables them to be stored in containers like std::vector.
40  */
41 class TemporarySubDirectory
42 {
43   public:
44     // Specify which compiler-generated methods we want
45     TemporarySubDirectory(const TemporarySubDirectory&) = delete;
46     TemporarySubDirectory& operator=(const TemporarySubDirectory&) = delete;
47 
48     /**
49      * Constructor.
50      *
51      * Creates a temporary subdirectory below the system temporary directory
52      * (such as /tmp).
53      *
54      * Throws an exception if the subdirectory cannot be created.
55      */
56     TemporarySubDirectory();
57 
58     /**
59      * Move constructor.
60      *
61      * Transfers ownership of a temporary subdirectory.
62      *
63      * @param subdirectory TemporarySubDirectory object being moved
64      */
65     TemporarySubDirectory(TemporarySubDirectory&& subdirectory) :
66         path{std::move(subdirectory.path)}
67     {
68         // Clear path in other object; after move path is in unspecified state
69         subdirectory.path.clear();
70     }
71 
72     /**
73      * Move assignment operator.
74      *
75      * Deletes the temporary subdirectory owned by this object.  Then transfers
76      * ownership of the temporary subdirectory owned by the other object.
77      *
78      * Throws an exception if an error occurs during the deletion.
79      *
80      * @param subdirectory TemporarySubDirectory object being moved
81      */
82     TemporarySubDirectory& operator=(TemporarySubDirectory&& subdirectory);
83 
84     /**
85      * Destructor.
86      *
87      * Deletes the temporary subdirectory if necessary.
88      */
89     ~TemporarySubDirectory()
90     {
91         try
92         {
93             remove();
94         }
95         catch (...)
96         {
97             // Destructors should not throw exceptions
98         }
99     }
100 
101     /**
102      * Deletes the temporary subdirectory.
103      *
104      * Does nothing if the subdirectory has already been deleted.
105      *
106      * Throws an exception if an error occurs during the deletion.
107      */
108     void remove();
109 
110     /**
111      * Returns the absolute path to the temporary subdirectory.
112      *
113      * Returns an empty path if the subdirectory has been deleted.
114      *
115      * @return temporary subdirectory path
116      */
117     const std::filesystem::path& getPath() const
118     {
119         return path;
120     }
121 
122   private:
123     /**
124      * Absolute path to the temporary subdirectory.
125      *
126      * Empty when subdirectory has been deleted.
127      */
128     std::filesystem::path path{};
129 };
130 
131 } // namespace phosphor::power::util
132