Thrill  0.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
temporary_directory.cpp
Go to the documentation of this file.
1 /*******************************************************************************
2  * thrill/vfs/temporary_directory.cpp
3  *
4  * Part of Project Thrill - http://project-thrill.org
5  *
6  * Copyright (C) 2015 Alexander Noe <[email protected]>
7  * Copyright (C) 2015-2016 Timo Bingmann <[email protected]>
8  *
9  * All rights reserved. Published under the BSD-2 license in the LICENSE file.
10  ******************************************************************************/
11 
13 
14 #include <thrill/common/logger.hpp>
16 
17 #if !defined(_MSC_VER)
18 
19 #include <dirent.h>
20 #include <unistd.h>
21 
22 #else
23 
24 #include <io.h>
25 #include <windows.h>
26 
27 #endif
28 
29 #include <string>
30 
31 namespace thrill {
32 namespace vfs {
33 
34 #if defined(_MSC_VER)
35 
37 
38  char temp_file_path[MAX_PATH + 1] = { 0 };
39  unsigned success = ::GetTempFileName(".", sample, 0, temp_file_path);
40  if (!success) {
41  throw common::ErrnoException(
42  "Could not allocate temporary directory "
43  + std::string(temp_file_path));
44  }
45 
46  if (!DeleteFile(temp_file_path)) {
47  throw common::ErrnoException(
48  "Could not create temporary directory "
49  + std::string(temp_file_path));
50  }
51 
52  if (!CreateDirectory(temp_file_path, nullptr)) {
53  throw common::ErrnoException(
54  "Could not create temporary directory "
55  + std::string(temp_file_path));
56  }
57 
58  return temp_file_path;
59 }
60 
62  const std::string& tmp_dir, bool do_rmdir) {
63 
64  WIN32_FIND_DATA ff_data;
65  HANDLE h = FindFirstFile((tmp_dir + "\\*").c_str(), &ff_data);
66 
67  if (h == INVALID_HANDLE_VALUE) {
68  throw common::ErrnoException(
69  "FindFirstFile failed:" + std::to_string(GetLastError()));
70  }
71 
72  do {
73  if (!(ff_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
74  std::string path = tmp_dir + "\\" + ff_data.cFileName;
75 
76  if (!DeleteFile(path.c_str())) {
77  sLOG1 << "Could not unlink temporary file" << path
78  << ":" << strerror(errno);
79  }
80  }
81  } while (FindNextFile(h, &ff_data) != 0);
82 
83  DWORD e = GetLastError();
84  if (e != ERROR_NO_MORE_FILES) {
85  throw common::ErrnoException(
86  "FindFirstFile failed:" + std::to_string(GetLastError()));
87  }
88 
89  if (!do_rmdir) return;
90 
91  if (!RemoveDirectory(tmp_dir.c_str())) {
92  throw common::ErrnoException(
93  "Could not remove temporary directory " + tmp_dir);
94  }
95 }
96 
97 #else
98 
100 
101  std::string tmp_dir = std::string(sample) + "XXXXXX";
102  // evil const_cast, but mkdtemp replaces the XXXXXX with something
103  // unique. it also mkdirs.
104  char* p = mkdtemp(const_cast<char*>(tmp_dir.c_str()));
105 
106  if (p == nullptr) {
108  "Could create temporary directory " + tmp_dir);
109  }
110 
111  return tmp_dir;
112 }
113 
115  const std::string& tmp_dir, bool do_rmdir) {
116  DIR* d = opendir(tmp_dir.c_str());
117  if (d == nullptr) {
119  "Could open temporary directory " + tmp_dir);
120  }
121 
122  struct dirent* de, entry;
123  while (readdir_r(d, &entry, &de) == 0 && de != nullptr) {
124  // skip ".", "..", and also hidden files (don't create them).
125  if (de->d_name[0] == '.') continue;
126 
127  std::string path = tmp_dir + "/" + de->d_name;
128  int r = unlink(path.c_str());
129  if (r != 0)
130  sLOG1 << "Could not unlink temporary file" << path
131  << ":" << strerror(errno);
132  }
133 
134  closedir(d);
135 
136  if (!do_rmdir) return;
137 
138  if (rmdir(tmp_dir.c_str()) != 0) {
139  sLOG1 << "Could not unlink temporary directory" << tmp_dir
140  << ":" << strerror(errno);
141  }
142 }
143 
144 #endif
145 
146 } // namespace vfs
147 } // namespace thrill
148 
149 /******************************************************************************/
An Exception which is thrown on system errors and contains errno information.
#define sLOG1
Definition: logger.hpp:38
static by_string to_string(int val)
convert to string
#define MAX_PATH
Definition: simple_glob.hpp:57
static std::string make_directory(const char *sample="thrill-testsuite-")
Create a temporary directory, returns its name without trailing /.
std::basic_string< char, std::char_traits< char >, Allocator< char > > string
string with Manager tracking
Definition: allocator.hpp:220
static void wipe_directory(const std::string &tmp_dir, bool do_rmdir)
wipe temporary directory NON RECURSIVELY!