#include <ctime>
#include <cstdio>
#include <sstream>
-#include <dirent.h>
+#include <fts.h>
#include <ecore-1/Ecore_File.h>
#include <eina-1/eina/eina_list.h>
#include <dpl/log/log.h>
{
Try {
Assert(path && "path is NULL");
+ FTS *fts;
+ FTSENT *ftsent;
+ std::string pth=path->getFullPath();
+ char * const paths[] = {const_cast<char * const>(pth.c_str()), NULL};
- DIR* dir = opendir(path->getFullPath().c_str());
- if (!dir) {
+ if ((fts = fts_open(paths, FTS_PHYSICAL|FTS_NOCHDIR, NULL)) == NULL) {
+ //ERROR
+ int error = errno;
+ LogError(__PRETTY_FUNCTION__ << ": fts_open on "
+ << pth
+ << " failed with error: "
+ << strerror(error));
return;
}
- errno = 0;
- struct dirent* entry = NULL;
- while ((entry = readdir(dir))) {
- if (event && event->checkCancelled()) {
- break;
- }
- if (!strncmp(entry->d_name, ".",
- 1) || !strncmp(entry->d_name, "..", 2)) {
- continue;
- }
- IPathPtr childPath = *path + entry->d_name;
- struct stat info;
- memset(&info, 0, sizeof(struct stat));
- if (lstat(childPath->getFullPath().c_str(), &info) == 0) {
- if (matchFilters(entry->d_name, info, filters)) {
- result.push_back(Node::resolve(childPath));
- }
- if (S_ISDIR(info.st_mode)) {
- find(childPath, filters, result, event);
- }
+ while ((ftsent = fts_read(fts)) != NULL) {
+ if(event && event->checkCancelled()) break;
+ switch (ftsent->fts_info) {
+ case FTS_DP:
+ //directory in postorder - do nothing
+ break;
+ case FTS_D:
+ case FTS_DC:
+ case FTS_F:
+ case FTS_SL:
+ case FTS_SLNONE:
+ case FTS_DEFAULT:
+ //regular files, symbolic links, directories in preorder
+ //and other file entries that can be processed further
+ if (matchFilters(ftsent->fts_name, *ftsent->fts_statp, filters)) {
+ IPathPtr childPath=IPath::create(ftsent->fts_path);
+ result.push_back(Node::resolve(childPath));
+ }
+ break;
+ case FTS_NS:
+ case FTS_NSOK:
+ case FTS_DOT:
+ case FTS_DNR:
+ case FTS_ERR:
+ default:
+ LogWarning(__PRETTY_FUNCTION__
+ << ": traversal failed with error: "
+ << strerror(ftsent->fts_errno));
+ ThrowMsg(Commons::PlatformException,
+ "Error reading directory");
}
}
- if (errno != 0) {
- ThrowMsg(Commons::PlatformException,
- "Error while reading directory.");
- }
-
- if (closedir(dir) != 0) {
+ if (fts_close(fts) == -1) {
+ int error = errno;
+ LogWarning(__PRETTY_FUNCTION__ << ": fts_close failed with error: "
+ << strerror(error));
ThrowMsg(Commons::PlatformException,
"Could not close platform node.");
}
#include <sys/types.h>
#include <cstdio>
#include <unistd.h>
+#include <fts.h>
#include <dirent.h>
#include <errno.h>
#include <pcrecpp.h>
{
Assert(path);
if (recursive) {
- DIR* dir = opendir(path->getFullPath().c_str());
- if (!dir) {
- LogError("File: " << path->getFullPath().c_str());
- ThrowMsg(Commons::PlatformException,
- "Node does not exist or access denied.");
+ FTS *fts;
+ FTSENT *ftsent;
+ int error = 0;
+ std::string pth=path->getFullPath();
+ char * const paths[] = {const_cast<char * const>(pth.c_str()), NULL};
+
+ if ((fts = fts_open(paths, FTS_PHYSICAL|FTS_NOCHDIR, NULL)) == NULL) {
+ //ERROR
+ error = errno;
+ LogError(__PRETTY_FUNCTION__ << ": fts_open on "
+ << pth
+ << " failed with error: "
+ << strerror(error));
+ ThrowMsg(Commons::PlatformException, "Failed to traverse Node");
}
- errno = 0;
- struct dirent *entry = NULL;
- while ((entry = readdir(dir))) {
- if (!strncmp(entry->d_name, ".",
- 1) || !strncmp(entry->d_name, "..", 2)) {
- continue;
- }
- IPathPtr subPath = *path + entry->d_name;
- struct stat info;
- memset(&info, 0, sizeof(struct stat));
- if (lstat(subPath->getFullPath().c_str(), &info) == 0) {
- Try {
- if (S_ISDIR(info.st_mode)) {
- removeAsDirectory(subPath, true);
- } else if (S_ISREG(info.st_mode)) {
- removeAsFile(subPath);
+
+ while ((ftsent = fts_read(fts)) != NULL) {
+ switch (ftsent->fts_info) {
+ case FTS_D:
+ //directory in preorder - do nothing
+ break;
+ case FTS_DP:
+ //directory in postorder - remove
+ errno = 0;
+ if (rmdir(ftsent->fts_accpath) != 0) {
+ if (errno == EEXIST) {
+ ThrowMsg(Commons::PlatformException,
+ "Node has child nodes.");
+ }
+ ThrowMsg(Commons::PlatformException,
+ "Error while removing platform node.");
}
- }
- Catch(Commons::PlatformException) {
- }
- // TODO: Not sure if above exception should be swallowed.
+ break;
+ case FTS_DC:
+ case FTS_F:
+ case FTS_NSOK:
+ case FTS_SL:
+ case FTS_SLNONE:
+ case FTS_DEFAULT:
+ {
+ //regular files and other objects that can safely be removed
+ IPathPtr file_path = IPath::create(ftsent->fts_path);
+ removeAsFile(file_path);
+ break;
+ }
+ case FTS_NS:
+ case FTS_DOT:
+ case FTS_DNR:
+ case FTS_ERR:
+ default:
+ LogWarning(__PRETTY_FUNCTION__
+ << ": traversal failed with error: "
+ << strerror(ftsent->fts_errno));
+ break;
}
}
- closedir(dir);
- }
- errno = 0;
- if (rmdir(path->getFullPath().c_str()) != 0) {
- if (errno == EEXIST) {
- ThrowMsg(Commons::PlatformException, "Node has child nodes.");
+ if (fts_close(fts) == -1) {
+ error = errno;
+ LogWarning(__PRETTY_FUNCTION__ << ": fts_close failed with error: "
+ << strerror(error));
+ }
+ } else {
+ if (rmdir(path->getFullPath().c_str()) != 0) {
+ if (errno == EEXIST) {
+ ThrowMsg(Commons::PlatformException, "Node has child nodes.");
+ }
+ ThrowMsg(Commons::PlatformException,
+ "Error while removing platform node.");
}
- ThrowMsg(Commons::PlatformException,
- "Error while removing platform node.");
}
}