regulators: Make TmpFile class common
A TmpFile class was implemented in two different test cases to
automatically create and delete temporary files.
Moved the TmpFile class into a standalone file so that the code could be
common among test cases. Improved the error handling.
Signed-off-by: Shawn McCarney <shawnmm@us.ibm.com>
Change-Id: Ifa8ddd3b442bcf8fbf0dc4d0a39dd9fc5f233e3f
diff --git a/phosphor-regulators/test/tmp_file.hpp b/phosphor-regulators/test/tmp_file.hpp
new file mode 100644
index 0000000..dd0a66c
--- /dev/null
+++ b/phosphor-regulators/test/tmp_file.hpp
@@ -0,0 +1,99 @@
+/**
+ * Copyright © 2020 IBM Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#pragma once
+
+#include <errno.h> // for errno
+#include <stdio.h> // for perror()
+#include <stdlib.h> // for mkstemp()
+#include <string.h> // for strerror()
+#include <unistd.h> // for close(), unlink()
+
+#include <stdexcept>
+#include <string>
+
+namespace phosphor::power::regulators
+{
+
+/**
+ * @class TmpFile
+ *
+ * Temporary file.
+ *
+ * File is created by the constructor and deleted by the destructor. The file
+ * name can be obtained from getName().
+ */
+class TmpFile
+{
+ public:
+ // Specify which compiler-generated methods we want
+ TmpFile(const TmpFile&) = delete;
+ TmpFile(TmpFile&&) = delete;
+ TmpFile& operator=(const TmpFile&) = delete;
+ TmpFile& operator=(TmpFile&&) = delete;
+
+ /**
+ * Constructor.
+ *
+ * Creates the temporary file.
+ */
+ TmpFile()
+ {
+ // Generate unique file name, create file, and open it. The XXXXXX
+ // characters are replaced by mkstemp() to make the file name unique.
+ char fileNameTemplate[17] = "/tmp/temp-XXXXXX";
+ int fd = mkstemp(fileNameTemplate);
+ if (fd == -1)
+ {
+ // If mkstemp() fails, throw an exception. No temporary file has
+ // been created and calling getName() would not work.
+ throw std::runtime_error{"Unable to create temporary file: " +
+ std::string{strerror(errno)}};
+ }
+
+ // Close file
+ if (close(fd) == -1)
+ {
+ // If close() fails, write a message to standard error but do not
+ // throw an exception. If an exception is thrown, the destructor
+ // will not be run and the temporary file will not be deleted.
+ perror("Unable to close temporary file");
+ }
+
+ // Save file name
+ fileName = fileNameTemplate;
+ }
+
+ const std::string& getName()
+ {
+ return fileName;
+ }
+
+ ~TmpFile()
+ {
+ // Delete temporary file
+ if (unlink(fileName.c_str()) == -1)
+ {
+ // If unlink() fails, write a message to standard error but do not
+ // throw an exception. Destructors must not throw exceptions.
+ perror("Unable to delete temporary file");
+ }
+ }
+
+ private:
+ std::string fileName{};
+};
+
+} // namespace phosphor::power::regulators