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