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