blob: 4ab6327eeaa84fa6635b4191e2a483494f2e221b [file] [log] [blame]
Shawn McCarneyb6f07c92020-09-03 21:49:21 -05001/**
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
17#include "temporary_file.hpp"
18
19#include <errno.h> // for errno
20#include <stdlib.h> // for mkstemp()
21#include <string.h> // for strerror()
22#include <unistd.h> // for close()
23
24#include <stdexcept>
25#include <string>
26
Shawn McCarney5f514442024-01-04 14:03:24 -060027namespace phosphor::power::util
Shawn McCarneyb6f07c92020-09-03 21:49:21 -050028{
29
Shawn McCarney5f514442024-01-04 14:03:24 -060030namespace fs = std::filesystem;
31
Shawn McCarneyb6f07c92020-09-03 21:49:21 -050032TemporaryFile::TemporaryFile()
33{
34 // Build template path required by mkstemp()
Patrick Williamsf5402192024-08-16 15:20:53 -040035 std::string templatePath =
36 fs::temp_directory_path() / "phosphor-power-XXXXXX";
Shawn McCarneyb6f07c92020-09-03 21:49:21 -050037
38 // Generate unique file name, create file, and open it. The XXXXXX
39 // characters are replaced by mkstemp() to make the file name unique.
40 int fd = mkstemp(templatePath.data());
41 if (fd == -1)
42 {
43 throw std::runtime_error{
44 std::string{"Unable to create temporary file: "} + strerror(errno)};
45 }
46
47 // Store path to temporary file
48 path = templatePath;
49
50 // Close file descriptor
51 if (close(fd) == -1)
52 {
53 // Save errno value; will likely change when we delete temporary file
54 int savedErrno = errno;
55
56 // Delete temporary file. The destructor won't be called because the
57 // exception below causes this constructor to exit without completing.
58 remove();
59
60 throw std::runtime_error{
61 std::string{"Unable to close temporary file: "} +
62 strerror(savedErrno)};
63 }
64}
65
66TemporaryFile& TemporaryFile::operator=(TemporaryFile&& file)
67{
68 // Verify not assigning object to itself (a = std::move(a))
69 if (this != &file)
70 {
71 // Delete temporary file owned by this object
72 remove();
73
74 // Move temporary file path from other object, transferring ownership
75 path = std::move(file.path);
76
77 // Clear path in other object; after move path is in unspecified state
78 file.path.clear();
79 }
80 return *this;
81}
82
83void TemporaryFile::remove()
84{
85 if (!path.empty())
86 {
87 // Delete temporary file from file system
88 fs::remove(path);
89
90 // Clear path to indicate file has been deleted
91 path.clear();
92 }
93}
94
Shawn McCarney5f514442024-01-04 14:03:24 -060095} // namespace phosphor::power::util