16e36587aSZane Shelley #include "util/temporary_file.hpp" 26e36587aSZane Shelley 36e36587aSZane Shelley #include <errno.h> // for errno 46e36587aSZane Shelley #include <stdlib.h> // for mkstemp() 56e36587aSZane Shelley #include <string.h> // for strerror() 66e36587aSZane Shelley #include <unistd.h> // for close() 76e36587aSZane Shelley 86e36587aSZane Shelley #include <stdexcept> 96e36587aSZane Shelley #include <string> 106e36587aSZane Shelley 116e36587aSZane Shelley namespace util 126e36587aSZane Shelley { 136e36587aSZane Shelley TemporaryFile()146e36587aSZane ShelleyTemporaryFile::TemporaryFile() 156e36587aSZane Shelley { 166e36587aSZane Shelley // Build template path required by mkstemp() 17*a0c724d3SPatrick Williams std::string templatePath = 18*a0c724d3SPatrick Williams fs::temp_directory_path() / "openpower-hw-diags-XXXXXX"; 196e36587aSZane Shelley 206e36587aSZane Shelley // Generate unique file name, create file, and open it. The XXXXXX 216e36587aSZane Shelley // characters are replaced by mkstemp() to make the file name unique. 226e36587aSZane Shelley int fd = mkstemp(templatePath.data()); 236e36587aSZane Shelley if (fd == -1) 246e36587aSZane Shelley { 256e36587aSZane Shelley throw std::runtime_error{ 266e36587aSZane Shelley std::string{"Unable to create temporary file: "} + strerror(errno)}; 276e36587aSZane Shelley } 286e36587aSZane Shelley 296e36587aSZane Shelley // Store path to temporary file 306e36587aSZane Shelley path = templatePath; 316e36587aSZane Shelley 326e36587aSZane Shelley // Close file descriptor 336e36587aSZane Shelley if (close(fd) == -1) 346e36587aSZane Shelley { 356e36587aSZane Shelley // Save errno value; will likely change when we delete temporary file 366e36587aSZane Shelley int savedErrno = errno; 376e36587aSZane Shelley 386e36587aSZane Shelley // Delete temporary file. The destructor won't be called because the 396e36587aSZane Shelley // exception below causes this constructor to exit without completing. 406e36587aSZane Shelley remove(); 416e36587aSZane Shelley 426e36587aSZane Shelley throw std::runtime_error{ 436e36587aSZane Shelley std::string{"Unable to close temporary file: "} + 446e36587aSZane Shelley strerror(savedErrno)}; 456e36587aSZane Shelley } 466e36587aSZane Shelley } 476e36587aSZane Shelley operator =(TemporaryFile && file)486e36587aSZane ShelleyTemporaryFile& TemporaryFile::operator=(TemporaryFile&& file) 496e36587aSZane Shelley { 506e36587aSZane Shelley // Verify not assigning object to itself (a = std::move(a)) 516e36587aSZane Shelley if (this != &file) 526e36587aSZane Shelley { 536e36587aSZane Shelley // Delete temporary file owned by this object 546e36587aSZane Shelley remove(); 556e36587aSZane Shelley 566e36587aSZane Shelley // Move temporary file path from other object, transferring ownership 576e36587aSZane Shelley path = std::move(file.path); 586e36587aSZane Shelley 596e36587aSZane Shelley // Clear path in other object; after move path is in unspecified state 606e36587aSZane Shelley file.path.clear(); 616e36587aSZane Shelley } 626e36587aSZane Shelley return *this; 636e36587aSZane Shelley } 646e36587aSZane Shelley remove()656e36587aSZane Shelleyvoid TemporaryFile::remove() 666e36587aSZane Shelley { 676e36587aSZane Shelley if (!path.empty()) 686e36587aSZane Shelley { 696e36587aSZane Shelley // Delete temporary file from file system 706e36587aSZane Shelley fs::remove(path); 716e36587aSZane Shelley 726e36587aSZane Shelley // Clear path to indicate file has been deleted 736e36587aSZane Shelley path.clear(); 746e36587aSZane Shelley } 756e36587aSZane Shelley } 766e36587aSZane Shelley 776e36587aSZane Shelley } // namespace util 78