Merge pull request #113 from danw/resilient_find
Be more resilient to directories disappearing during startup
diff --git a/find.cc b/find.cc
index 0860847..c6a4155 100644
--- a/find.cc
+++ b/find.cc
@@ -793,6 +793,9 @@
if (!is_initialized_) {
ScopedTimeReporter tr("init find emulator time");
root_.reset(ConstructDirectoryTree(""));
+ if (!root_) {
+ ERROR("FindEmulator: Cannot open root directory");
+ }
ResolveSymlinks();
LOG_STAT("%d find nodes", node_cnt_);
is_initialized_ = true;
@@ -914,8 +917,14 @@
DirentNode* ConstructDirectoryTree(const string& path) {
DIR* dir = opendir(path.empty() ? "." : path.c_str());
- if (!dir)
- PERROR("opendir failed: %s", path.c_str());
+ if (!dir) {
+ if (errno == ENOENT) {
+ LOG("opendir failed: %s", path.c_str());
+ return NULL;
+ } else {
+ PERROR("opendir failed: %s", path.c_str());
+ }
+ }
DirentDirNode* n = new DirentDirNode(path);
@@ -940,6 +949,9 @@
}
if (d_type == DT_DIR) {
c = ConstructDirectoryTree(npath);
+ if (c == NULL) {
+ continue;
+ }
} else if (d_type == DT_LNK) {
auto s = new DirentSymlinkNode(npath);
symlinks_.push_back(make_pair(npath, s));
@@ -992,7 +1004,12 @@
if (type == DT_DIR) {
if (path.find('/') == string::npos) {
- s->set_to(ConstructDirectoryTree(path));
+ DirentNode* dir = ConstructDirectoryTree(path);
+ if (dir != NULL) {
+ s->set_to(dir);
+ } else {
+ s->set_errno(errno);
+ }
}
} else if (type != DT_LNK && type != DT_UNKNOWN) {
s->set_to(new DirentFileNode(path, type));