1 #include "util/temporary_file.hpp" 2 3 #include <errno.h> // for errno 4 #include <stdlib.h> // for mkstemp() 5 #include <string.h> // for strerror() 6 #include <unistd.h> // for close() 7 8 #include <stdexcept> 9 #include <string> 10 11 namespace util 12 { 13 14 TemporaryFile::TemporaryFile() 15 { 16 // Build template path required by mkstemp() 17 std::string templatePath = 18 fs::temp_directory_path() / "openpower-hw-diags-XXXXXX"; 19 20 // Generate unique file name, create file, and open it. The XXXXXX 21 // characters are replaced by mkstemp() to make the file name unique. 22 int fd = mkstemp(templatePath.data()); 23 if (fd == -1) 24 { 25 throw std::runtime_error{ 26 std::string{"Unable to create temporary file: "} + strerror(errno)}; 27 } 28 29 // Store path to temporary file 30 path = templatePath; 31 32 // Close file descriptor 33 if (close(fd) == -1) 34 { 35 // Save errno value; will likely change when we delete temporary file 36 int savedErrno = errno; 37 38 // Delete temporary file. The destructor won't be called because the 39 // exception below causes this constructor to exit without completing. 40 remove(); 41 42 throw std::runtime_error{ 43 std::string{"Unable to close temporary file: "} + 44 strerror(savedErrno)}; 45 } 46 } 47 48 TemporaryFile& TemporaryFile::operator=(TemporaryFile&& file) 49 { 50 // Verify not assigning object to itself (a = std::move(a)) 51 if (this != &file) 52 { 53 // Delete temporary file owned by this object 54 remove(); 55 56 // Move temporary file path from other object, transferring ownership 57 path = std::move(file.path); 58 59 // Clear path in other object; after move path is in unspecified state 60 file.path.clear(); 61 } 62 return *this; 63 } 64 65 void TemporaryFile::remove() 66 { 67 if (!path.empty()) 68 { 69 // Delete temporary file from file system 70 fs::remove(path); 71 72 // Clear path to indicate file has been deleted 73 path.clear(); 74 } 75 } 76 77 } // namespace util 78