Add TemporaryFile class
Added support for creating temporary file
- Constructor creates the temporary file.
- Destructor deletes the file.
- Provided remove function to delete the file.
Signed-off-by: Jayanth Othayoth <ojayanth@in.ibm.com>
Change-Id: I2a5e81af8cf4f4621e5ec6437b936126b7e9ba5a
diff --git a/meson.build b/meson.build
index e31f0c7..d39f9f5 100644
--- a/meson.build
+++ b/meson.build
@@ -90,6 +90,7 @@
'extensions/phal/create_pel.cpp',
'extensions/phal/phal_error.cpp',
'extensions/phal/dump_utils.cpp',
+ 'temporary_file.cpp',
]
extra_dependencies += [
dependency('libdt-api'),
diff --git a/temporary_file.cpp b/temporary_file.cpp
new file mode 100644
index 0000000..34a18ca
--- /dev/null
+++ b/temporary_file.cpp
@@ -0,0 +1,64 @@
+#include "temporary_file.hpp"
+
+#include <fmt/format.h>
+#include <unistd.h>
+
+#include <phosphor-logging/elog-errors.hpp>
+
+#include <cerrno>
+#include <cstdlib>
+#include <stdexcept>
+#include <string>
+
+namespace openpower::util
+{
+using namespace phosphor::logging;
+
+TemporaryFile::TemporaryFile()
+{
+ // Build template path required by mkstemp()
+ std::string templatePath =
+ fs::temp_directory_path() / "openpower-proc-control-XXXXXX";
+
+ // Generate unique file name, create file, and open it. The XXXXXX
+ // characters are replaced by mkstemp() to make the file name unique.
+ int fd = mkstemp(templatePath.data());
+ if (fd == -1)
+ {
+ throw std::runtime_error{
+ std::string{"Unable to create temporary file: "} + strerror(errno)};
+ }
+
+ // Store path to temporary file
+ path = templatePath;
+
+ // Close file descriptor
+ if (close(fd) == -1)
+ {
+ // Save errno value; will likely change when we delete temporary file
+ int savedErrno = errno;
+
+ // Delete temporary file. The destructor won't be called because
+ // the exception below causes this constructor to exit without
+ // completing.
+ remove();
+
+ throw std::runtime_error{
+ std::string{"Unable to close temporary file: "} +
+ strerror(savedErrno)};
+ }
+}
+
+void TemporaryFile::remove()
+{
+ if (!path.empty())
+ {
+ // Delete temporary file from file system
+ fs::remove(path);
+
+ // Clear path to indicate file has been deleted
+ path.clear();
+ }
+}
+
+} // namespace openpower::util
diff --git a/temporary_file.hpp b/temporary_file.hpp
new file mode 100644
index 0000000..b073b32
--- /dev/null
+++ b/temporary_file.hpp
@@ -0,0 +1,87 @@
+#pragma once
+
+#include <filesystem>
+#include <utility>
+
+namespace openpower::util
+{
+
+namespace fs = std::filesystem;
+
+/**
+ * @class TemporaryFile
+ *
+ * A temporary file in the file system.
+ *
+ * The temporary file is created by the constructor. The absolute path to the
+ * file can be obtained using getPath().
+ *
+ * The temporary file can be deleted by calling remove(). Otherwise the file
+ * will be deleted by the destructor.
+ *
+ */
+class TemporaryFile
+{
+ public:
+ // Specify which compiler-generated methods we want
+ TemporaryFile(const TemporaryFile&) = delete;
+ TemporaryFile(TemporaryFile&&) = delete;
+ TemporaryFile& operator=(const TemporaryFile&) = delete;
+
+ /**
+ * Constructor.
+ *
+ * Creates a temporary file in the temporary directory (normally /tmp).
+ *
+ * Throws an exception if the file cannot be created.
+ */
+ TemporaryFile();
+
+ /**
+ * Destructor.
+ *
+ * Deletes the temporary file if necessary.
+ */
+ ~TemporaryFile()
+ {
+ try
+ {
+ remove();
+ }
+ catch (...)
+ {
+ // Destructors should not throw exceptions
+ }
+ }
+
+ /**
+ * Deletes the temporary file.
+ *
+ * Does nothing if the file has already been deleted.
+ *
+ * Log error message if an error occurs during the deletion.
+ */
+ void remove();
+
+ /**
+ * Returns the absolute path to the temporary file.
+ *
+ * Returns an empty path if the file has been deleted.
+ *
+ * @return temporary file path
+ */
+ const fs::path& getPath() const
+ {
+ return path;
+ }
+
+ private:
+ /**
+ * Absolute path to the temporary file.
+ *
+ * Empty when file has been deleted.
+ */
+ fs::path path{};
+};
+
+} // namespace openpower::util