16 #include <ndb_global.h>
19 #include <util/basestring_vsnprintf.h>
30 bool is_regular_file(
struct dirent* dp)
const {
31 #ifdef _DIRENT_HAVE_D_TYPE
36 if(dp->d_type != DT_UNKNOWN)
37 return (dp->d_type == DT_REG);
40 basestring_snprintf(m_buf, PATH_MAX,
41 "%s/%s", m_path, dp->d_name);
44 if (lstat(m_buf, &buf))
47 return S_ISREG(buf.st_mode);
54 m_buf =
new char[PATH_MAX];
62 int open(
const char* path){
63 if ((m_dirp = opendir(path)) == NULL){
77 const char* next_entry(
bool& is_reg)
79 struct dirent* dp = readdir(m_dirp);
84 is_reg = is_regular_file(dp);
93 WIN32_FIND_DATA m_find_data;
96 bool is_dir(
const WIN32_FIND_DATA find_data)
const {
97 return (find_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY);
99 bool is_regular_file(
const WIN32_FIND_DATA find_data)
const {
100 return !is_dir(find_data);
106 m_find_handle(INVALID_HANDLE_VALUE) {};
112 int open(
const char* path){
113 char path_buf[PATH_MAX+2];
115 basestring_snprintf(path_buf,
sizeof(path_buf),
"%s\\*", path);
116 m_find_handle = FindFirstFile(path_buf, &m_find_data);
117 if(m_find_handle == INVALID_HANDLE_VALUE)
119 if (GetLastError() == ERROR_FILE_NOT_FOUND)
130 FindClose(m_find_handle);
131 m_find_handle = NULL;
134 const char* next_entry(
bool& is_reg)
136 if (m_first || FindNextFile(m_find_handle, &m_find_data))
139 is_reg = is_regular_file(m_find_data);
140 return m_find_data.cFileName;
149 NdbDir::Iterator::Iterator() :
154 NdbDir::Iterator::~Iterator()
160 int NdbDir::Iterator::open(
const char* path)
162 return m_impl.open(path);
165 void NdbDir::Iterator::close(
void)
170 const char* NdbDir::Iterator::next_file(
void)
174 while((name = m_impl.next_entry(is_reg)) != NULL){
181 const char* NdbDir::Iterator::next_entry(
void)
184 return m_impl.next_entry(is_reg);
187 mode_t NdbDir::u_r(
void) {
return IF_WIN(0, S_IRUSR); };
188 mode_t NdbDir::u_w(
void) {
return IF_WIN(0, S_IWUSR); };
189 mode_t NdbDir::u_x(
void) {
return IF_WIN(0, S_IXUSR); };
191 mode_t NdbDir::g_r(
void) {
return IF_WIN(0, S_IRGRP); };
192 mode_t NdbDir::g_w(
void) {
return IF_WIN(0, S_IWGRP); };
193 mode_t NdbDir::g_x(
void) {
return IF_WIN(0, S_IXGRP); };
195 mode_t NdbDir::o_r(
void) {
return IF_WIN(0, S_IROTH); };
196 mode_t NdbDir::o_w(
void) {
return IF_WIN(0, S_IWOTH); };
197 mode_t NdbDir::o_x(
void) {
return IF_WIN(0, S_IXOTH); };
201 NdbDir::create(
const char *dir, mode_t
mode,
bool ignore_existing)
204 if (CreateDirectory(dir, NULL) == 0)
206 if (ignore_existing &&
207 GetLastError() == ERROR_ALREADY_EXISTS)
211 "Failed to create directory '%s', error: %d\n",
212 dir, GetLastError());
216 if (mkdir(dir, mode) != 0)
218 if (ignore_existing && errno == EEXIST)
222 "Failed to create directory '%s', error: %d\n",
234 DWORD len = GetTempPath(0, NULL);
235 m_path =
new char[len];
236 if (GetTempPath(len, (
char*)m_path) == 0)
239 char* tmp = getenv(
"TMPDIR");
247 NdbDir::Temp::~Temp()
256 NdbDir::Temp::path(
void)
const {
262 NdbDir::remove(
const char* path)
265 if (RemoveDirectory(path) != 0)
268 if (rmdir(path) == 0)
275 NdbDir::remove_recursive(
const char* dir,
bool only_contents)
278 if (basestring_snprintf(path,
sizeof(path),
279 "%s%s", dir, DIR_SEPARATOR) < 0) {
280 fprintf(stderr,
"Too long path to remove: '%s'\n", dir);
283 int start_len = strlen(path);
289 if (iter.open(path) != 0)
291 fprintf(stderr,
"Failed to open iterator for '%s'\n",
296 while ((name = iter.next_entry()) != NULL)
298 if ((strcmp(
".", name) == 0) || (strcmp(
"..", name) == 0))
301 int end_len, len = strlen(path);
302 if ((end_len = basestring_snprintf(path + len,
sizeof(path) - len,
305 fprintf(stderr,
"Too long path detected: '%s'+'%s'\n",
310 if (unlink(path) == 0 || NdbDir::remove(path) ==
true)
319 int pos = len + end_len;
320 if (basestring_snprintf(path + pos,
sizeof(path) - pos,
321 "%s", DIR_SEPARATOR) < 0)
323 fprintf(stderr,
"Too long path detected: '%s'+'%s'\n",
324 path, DIR_SEPARATOR);
332 int len = strlen(path);
335 char * prev_slash = strrchr(path, IF_WIN(
'\\',
'/'));
336 if (len > start_len && prev_slash)
339 assert(prev_slash > path && prev_slash < path +
sizeof(path));
345 if (only_contents ==
false && NdbDir::remove(dir) ==
false)
348 "Failed to remove directory '%s', error: %d\n",
361 NdbDir::chdir(
const char* path)
363 return ::chdir(path);
368 #include <NdbTap.hpp>
372 fprintf(stderr, "failed at line %d\n", __LINE__ ); \
376 build_tree(
const char* path)
379 CHECK(NdbDir::create(path));
382 for (
int i = 8;
i < 14;
i++){
383 basestring_snprintf(tmp,
sizeof(tmp),
"%s%sfile%d", path, DIR_SEPARATOR,
i);
384 fclose(fopen(tmp,
"w"));
388 for (
int i = 8;
i < 14;
i++){
389 basestring_snprintf(tmp,
sizeof(tmp),
"%s%sdir%d", path, DIR_SEPARATOR,
i);
390 CHECK(NdbDir::create(tmp));
393 for (
int j = 0; j < 6; j++){
394 basestring_snprintf(tmp,
sizeof(tmp),
"%s%sdir%d%sfile%d",
395 path, DIR_SEPARATOR,
i, DIR_SEPARATOR, j);
396 fclose(fopen(tmp,
"w"));
403 basestring_snprintf(tmp2,
sizeof(tmp2),
"%s%ssymlink", path, DIR_SEPARATOR);
404 CHECK(symlink(tmp, tmp2) == 0);
409 gone(
const char *dir) {
410 return (access(dir, F_OK) == -1 && errno == ENOENT);
417 basestring_snprintf(path,
sizeof(path),
"%s%s%s",
418 tempdir.path(), DIR_SEPARATOR,
"ndbdir_test");
420 printf(
"Using directory '%s'\n", path);
423 if (access(path, F_OK) == 0)
424 CHECK(NdbDir::remove_recursive(path));
431 CHECK(iter.open(path) == 0);
434 while((name = iter.next_file()) != NULL)
439 printf(
"Found %d files\n", num_files);
440 CHECK(num_files == 6);
444 CHECK(NdbDir::remove_recursive(path));
448 fprintf(stderr,
"Checking that proper error is returned when "
449 "opening non existing directory\n");
450 CHECK(!NdbDir::remove_recursive(path));
455 CHECK(NdbDir::remove_recursive(path,
true));
459 CHECK(NdbDir::remove_recursive(path));
463 CHECK(!NdbDir::remove_recursive(path));
467 CHECK(NdbDir::create(path,
468 NdbDir::u_rwx() | NdbDir::g_r() | NdbDir::o_r()));
470 CHECK(NdbDir::remove_recursive(path));
474 CHECK(NdbDir::create(path, NdbDir::u_rwx()));
476 CHECK(NdbDir::create(path, NdbDir::u_rwx(),
true ));
478 CHECK(NdbDir::remove_recursive(path));
481 printf(
"Testing NdbDir::chdir...\n");
483 CHECK(NdbDir::chdir(path) != 0);
489 CHECK(NdbDir::chdir(path) == 0);
492 CHECK(NdbDir::chdir(tempdir.path()) == 0);
495 CHECK(NdbDir::remove_recursive(path));