blob: dd0a66cadaf256ffcd2bb2c5db255d865c84c481 [file] [log] [blame]
Shawn McCarney80c0b042020-03-27 12:08:53 -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#pragma once
17
18#include <errno.h> // for errno
19#include <stdio.h> // for perror()
20#include <stdlib.h> // for mkstemp()
21#include <string.h> // for strerror()
22#include <unistd.h> // for close(), unlink()
23
24#include <stdexcept>
25#include <string>
26
27namespace phosphor::power::regulators
28{
29
30/**
31 * @class TmpFile
32 *
33 * Temporary file.
34 *
35 * File is created by the constructor and deleted by the destructor. The file
36 * name can be obtained from getName().
37 */
38class TmpFile
39{
40 public:
41 // Specify which compiler-generated methods we want
42 TmpFile(const TmpFile&) = delete;
43 TmpFile(TmpFile&&) = delete;
44 TmpFile& operator=(const TmpFile&) = delete;
45 TmpFile& operator=(TmpFile&&) = delete;
46
47 /**
48 * Constructor.
49 *
50 * Creates the temporary file.
51 */
52 TmpFile()
53 {
54 // Generate unique file name, create file, and open it. The XXXXXX
55 // characters are replaced by mkstemp() to make the file name unique.
56 char fileNameTemplate[17] = "/tmp/temp-XXXXXX";
57 int fd = mkstemp(fileNameTemplate);
58 if (fd == -1)
59 {
60 // If mkstemp() fails, throw an exception. No temporary file has
61 // been created and calling getName() would not work.
62 throw std::runtime_error{"Unable to create temporary file: " +
63 std::string{strerror(errno)}};
64 }
65
66 // Close file
67 if (close(fd) == -1)
68 {
69 // If close() fails, write a message to standard error but do not
70 // throw an exception. If an exception is thrown, the destructor
71 // will not be run and the temporary file will not be deleted.
72 perror("Unable to close temporary file");
73 }
74
75 // Save file name
76 fileName = fileNameTemplate;
77 }
78
79 const std::string& getName()
80 {
81 return fileName;
82 }
83
84 ~TmpFile()
85 {
86 // Delete temporary file
87 if (unlink(fileName.c_str()) == -1)
88 {
89 // If unlink() fails, write a message to standard error but do not
90 // throw an exception. Destructors must not throw exceptions.
91 perror("Unable to delete temporary file");
92 }
93 }
94
95 private:
96 std::string fileName{};
97};
98
99} // namespace phosphor::power::regulators