mxnet
filesystem.h
Go to the documentation of this file.
1 
7 #ifndef DMLC_FILESYSTEM_H_
8 #define DMLC_FILESYSTEM_H_
9 
10 #include <dmlc/logging.h>
11 #include <dmlc/io.h>
12 #include <algorithm>
13 #include <string>
14 #include <vector>
15 #include <random>
16 
17 /* platform specific headers */
18 #ifdef _WIN32
19 #define NOMINMAX
20 #include <windows.h>
21 #include <Shlwapi.h>
22 #pragma comment(lib, "Shlwapi.lib")
23 #else // _WIN32
24 #include <unistd.h>
25 #include <sys/stat.h>
26 #include <sys/types.h>
27 #endif // _WIN32
28 
29 namespace dmlc {
30 
55  public:
61  explicit TemporaryDirectory(bool verbose = false)
62  : verbose_(verbose) {
63 #if _WIN32
64  /* locate the root directory of temporary area */
65  char tmproot[MAX_PATH] = {0};
66  const DWORD dw_retval = GetTempPathA(MAX_PATH, tmproot);
67  if (dw_retval > MAX_PATH || dw_retval == 0) {
68  LOG(FATAL) << "TemporaryDirectory(): "
69  << "Could not create temporary directory";
70  }
71  /* generate a unique 8-letter alphanumeric string */
72  const std::string letters = "abcdefghijklmnopqrstuvwxyz0123456789_";
73  std::string uniqstr(8, '\0');
74  std::random_device rd;
75  std::mt19937 gen(rd());
76  std::uniform_int_distribution<int> dis(0, letters.length() - 1);
77  std::generate(uniqstr.begin(), uniqstr.end(),
78  [&dis, &gen, &letters]() -> char {
79  return letters[dis(gen)];
80  });
81  /* combine paths to get the name of the temporary directory */
82  char tmpdir[MAX_PATH] = {0};
83  PathCombineA(tmpdir, tmproot, uniqstr.c_str());
84  if (!CreateDirectoryA(tmpdir, NULL)) {
85  LOG(FATAL) << "TemporaryDirectory(): "
86  << "Could not create temporary directory";
87  }
88  path = std::string(tmpdir);
89 #else // _WIN32
90  std::string tmproot; /* root directory of temporary area */
91  std::string dirtemplate; /* template for temporary directory name */
92  /* Get TMPDIR env variable or fall back to /tmp/ */
93  {
94  const char* tmpenv = getenv("TMPDIR");
95  if (tmpenv) {
96  tmproot = std::string(tmpenv);
97  // strip trailing forward slashes
98  while (tmproot.length() != 0 && tmproot[tmproot.length() - 1] == '/') {
99  tmproot.resize(tmproot.length() - 1);
100  }
101  } else {
102  tmproot = "/tmp";
103  }
104  }
105  dirtemplate = tmproot + "/tmpdir.XXXXXX";
106  std::vector<char> dirtemplate_buf(dirtemplate.begin(), dirtemplate.end());
107  dirtemplate_buf.push_back('\0');
108  char* tmpdir = mkdtemp(&dirtemplate_buf[0]);
109  if (!tmpdir) {
110  LOG(FATAL) << "TemporaryDirectory(): "
111  << "Could not create temporary directory";
112  }
113  path = std::string(tmpdir);
114 #endif // _WIN32
115  if (verbose_) {
116  LOG(INFO) << "Created temporary directory " << path;
117  }
118  }
119 
122  RecursiveDelete(path);
123  }
124 
126  std::string path;
127 
128  private:
130  bool verbose_;
131 
136  inline bool IsSymlink(const std::string& path) {
137 #ifdef _WIN32
138  DWORD attr = GetFileAttributesA(path.c_str());
139  CHECK_NE(attr, INVALID_FILE_ATTRIBUTES)
140  << "dmlc::TemporaryDirectory::IsSymlink(): Unable to read file attributes";
141  return attr & FILE_ATTRIBUTE_REPARSE_POINT;
142 #else // _WIN32
143  struct stat sb;
144  CHECK_EQ(lstat(path.c_str(), &sb), 0)
145  << "dmlc::TemporaryDirectory::IsSymlink(): Unable to read file attributes";
146  return S_ISLNK(sb.st_mode);
147 #endif // _WIN32
148  }
149 
154  void RecursiveDelete(const std::string& path);
155 };
156 
157 } // namespace dmlc
158 #endif // DMLC_FILESYSTEM_H_
std::string path
Full path of the temporary directory.
Definition: filesystem.h:126
TemporaryDirectory(bool verbose=false)
Default constructor. Creates a new temporary directory with a unique name.
Definition: filesystem.h:61
namespace for dmlc
Definition: array_view.h:12
~TemporaryDirectory()
Destructor. Will perform recursive deletion via RecursiveDelete()
Definition: filesystem.h:121
Manager class for temporary directories. Whenever a new TemporaryDirectory object is constructed...
Definition: filesystem.h:54