Thrill  0.1
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>
17 
18 #if !defined(_MSC_VER)
19 
20 #include <dirent.h>
21 #include <unistd.h>
22 
23 #else
24 
25 #include <io.h>
26 #include <windows.h>
27 
28 #endif
29 
30 #include <string>
31 
32 namespace thrill {
33 namespace vfs {
34 
35 #if defined(_MSC_VER)
36 
38 
39  char temp_file_path[MAX_PATH + 1] = { 0 };
40  unsigned success = ::GetTempFileName(".", sample, 0, temp_file_path);
41  if (!success) {
42  throw common::ErrnoException(
43  "Could not allocate temporary directory "
44  + std::string(temp_file_path));
45  }
46 
47  if (!DeleteFile(temp_file_path)) {
48  throw common::ErrnoException(
49  "Could not create temporary directory "
50  + std::string(temp_file_path));
51  }
52 
53  if (!CreateDirectory(temp_file_path, nullptr)) {
54  throw common::ErrnoException(
55  "Could not create temporary directory "
56  + std::string(temp_file_path));
57  }
58 
59  return temp_file_path;
60 }
61 
63  const std::string& tmp_dir, bool do_rmdir) {
64 
65  WIN32_FIND_DATA ff_data;
66  HANDLE h = FindFirstFile((tmp_dir + "\\*").c_str(), &ff_data);
67 
68  if (h == INVALID_HANDLE_VALUE) {
69  throw common::ErrnoException(
70  "FindFirstFile failed:" + std::to_string(GetLastError()));
71  }
72 
73  do {
74  if (!(ff_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
75  std::string path = tmp_dir + "\\" + ff_data.cFileName;
76 
77  if (!DeleteFile(path.c_str())) {
78  sLOG1 << "Could not unlink temporary file" << path
79  << ":" << strerror(errno);
80  }
81  }
82  } while (FindNextFile(h, &ff_data) != 0);
83 
84  DWORD e = GetLastError();
85  if (e != ERROR_NO_MORE_FILES) {
86  throw common::ErrnoException(
87  "FindFirstFile failed:" + std::to_string(GetLastError()));
88  }
89 
90  if (!do_rmdir) return;
91 
92  if (!RemoveDirectory(tmp_dir.c_str())) {
93  throw common::ErrnoException(
94  "Could not remove temporary directory " + tmp_dir);
95  }
96 }
97 
98 #else
99 
101 
102  std::string tmp_dir = std::string(sample) + "XXXXXX";
103  // evil const_cast, but mkdtemp replaces the XXXXXX with something
104  // unique. it also mkdirs.
105  char* p = mkdtemp(const_cast<char*>(tmp_dir.c_str()));
106 
107  if (p == nullptr) {
109  "Could create temporary directory " + tmp_dir);
110  }
111 
112  return tmp_dir;
113 }
114 
116  const std::string& tmp_dir, bool do_rmdir) {
117  DIR* d = opendir(tmp_dir.c_str());
118  if (d == nullptr) {
120  "Could open temporary directory " + tmp_dir);
121  }
122 
123  struct dirent* de;
124  while ((de = common::ts_readdir(d)) != nullptr) {
125  // skip ".", "..", and also hidden files (don't create them).
126  if (de->d_name[0] == '.') continue;
127 
128  std::string path = tmp_dir + "/" + de->d_name;
129  int r = unlink(path.c_str());
130  if (r != 0)
131  sLOG1 << "Could not unlink temporary file" << path
132  << ":" << strerror(errno);
133  }
134 
135  closedir(d);
136 
137  if (!do_rmdir) return;
138 
139  if (rmdir(tmp_dir.c_str()) != 0) {
140  sLOG1 << "Could not unlink temporary directory" << tmp_dir
141  << ":" << strerror(errno);
142  }
143 }
144 
145 #endif
146 
147 } // namespace vfs
148 } // namespace thrill
149 
150 /******************************************************************************/
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
struct dirent * ts_readdir(DIR *dirp)
mutex-locked readdir() call
Definition: porting.cpp:153
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!