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