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