blob: 514d818024041a138d00931100fb5efc8442accc [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
27namespace phosphor::power::regulators
28{
29
30TemporaryFile::TemporaryFile()
31{
32 // Build template path required by mkstemp()
33 std::string templatePath =
34 fs::temp_directory_path() / "phosphor-regulators-XXXXXX";
35
36 // Generate unique file name, create file, and open it. The XXXXXX
37 // characters are replaced by mkstemp() to make the file name unique.
38 int fd = mkstemp(templatePath.data());
39 if (fd == -1)
40 {
41 throw std::runtime_error{
42 std::string{"Unable to create temporary file: "} + strerror(errno)};
43 }
44
45 // Store path to temporary file
46 path = templatePath;
47
48 // Close file descriptor
49 if (close(fd) == -1)
50 {
51 // Save errno value; will likely change when we delete temporary file
52 int savedErrno = errno;
53
54 // Delete temporary file. The destructor won't be called because the
55 // exception below causes this constructor to exit without completing.
56 remove();
57
58 throw std::runtime_error{
59 std::string{"Unable to close temporary file: "} +
60 strerror(savedErrno)};
61 }
62}
63
64TemporaryFile& TemporaryFile::operator=(TemporaryFile&& file)
65{
66 // Verify not assigning object to itself (a = std::move(a))
67 if (this != &file)
68 {
69 // Delete temporary file owned by this object
70 remove();
71
72 // Move temporary file path from other object, transferring ownership
73 path = std::move(file.path);
74
75 // Clear path in other object; after move path is in unspecified state
76 file.path.clear();
77 }
78 return *this;
79}
80
81void TemporaryFile::remove()
82{
83 if (!path.empty())
84 {
85 // Delete temporary file from file system
86 fs::remove(path);
87
88 // Clear path to indicate file has been deleted
89 path.clear();
90 }
91}
92
93} // namespace phosphor::power::regulators