diff options
Diffstat (limited to 'find.cc')
| -rw-r--r-- | find.cc | 63 |
1 files changed, 39 insertions, 24 deletions
@@ -150,7 +150,7 @@ class DirentNode { virtual const DirentNode* FindDir(StringPiece) const { return NULL; } - virtual bool RunFind(const FindCommand& fc, int d, + virtual bool RunFind(const FindCommand& fc, const Loc& loc, int d, string* path, unordered_map<const DirentNode*, string>* cur_read_dirs, vector<string>& out) const = 0; @@ -185,7 +185,7 @@ class DirentFileNode : public DirentNode { : DirentNode(name), type_(type) { } - virtual bool RunFind(const FindCommand& fc, int d, + virtual bool RunFind(const FindCommand& fc, const Loc&, int d, string* path, unordered_map<const DirentNode*, string>*, vector<string>& out) const override { @@ -255,15 +255,15 @@ class DirentDirNode : public DirentNode { return NULL; } - virtual bool RunFind(const FindCommand& fc, int d, + virtual bool RunFind(const FindCommand& fc, const Loc& loc, int d, string* path, unordered_map<const DirentNode*, string>* cur_read_dirs, vector<string>& out) const override { ScopedReadDirTracker srdt(this, *path, cur_read_dirs); if (!srdt.ok()) { - fprintf(stderr, "FindEmulator: find: File system loop detected; `%s' is " - "part of the same file system loop as `%s'.\n", - path->c_str(), srdt.conflicted().c_str()); + WARN_LOC(loc, "FindEmulator: find: File system loop detected; `%s' " + "is part of the same file system loop as `%s'.", + path->c_str(), srdt.conflicted().c_str()); return true; } @@ -292,7 +292,7 @@ class DirentDirNode : public DirentNode { if ((*path)[path->size()-1] != '/') *path += '/'; *path += c->base(); - if (!c->RunFind(fc, d + 1, path, cur_read_dirs, out)) + if (!c->RunFind(fc, loc, d + 1, path, cur_read_dirs, out)) return false; path->resize(orig_path_size); } @@ -320,7 +320,7 @@ class DirentDirNode : public DirentNode { if ((*path)[path->size()-1] != '/') *path += '/'; *path += c->base(); - if (!c->RunFind(fc, d + 1, path, cur_read_dirs, out)) + if (!c->RunFind(fc, loc, d + 1, path, cur_read_dirs, out)) return false; path->resize(orig_path_size); } @@ -330,7 +330,7 @@ class DirentDirNode : public DirentNode { if ((*path)[path->size()-1] != '/') *path += '/'; *path += c->base(); - if (!c->RunFind(fc, d + 1, path, cur_read_dirs, out)) + if (!c->RunFind(fc, loc, d + 1, path, cur_read_dirs, out)) return false; path->resize(orig_path_size); } @@ -360,7 +360,7 @@ class DirentSymlinkNode : public DirentNode { return NULL; } - virtual bool RunFind(const FindCommand& fc, int d, + virtual bool RunFind(const FindCommand& fc, const Loc& loc, int d, string* path, unordered_map<const DirentNode*, string>* cur_read_dirs, vector<string>& out) const override { @@ -368,8 +368,8 @@ class DirentSymlinkNode : public DirentNode { if (fc.follows_symlinks && errno_ != ENOENT) { if (errno_) { if (fc.type != FindCommandType::FINDLEAVES) { - fprintf(stderr, "FindEmulator: find: `%s': %s\n", - path->c_str(), strerror(errno_)); + WARN_LOC(loc, "FindEmulator: find: `%s': %s", + path->c_str(), strerror(errno_)); } return true; } @@ -379,7 +379,7 @@ class DirentSymlinkNode : public DirentNode { return false; } - return to_->RunFind(fc, d, path, cur_read_dirs, out); + return to_->RunFind(fc, loc, d, path, cur_read_dirs, out); } PrintIfNecessary(fc, *path, type, d, out); return true; @@ -783,7 +783,7 @@ class FindEmulatorImpl : public FindEmulator { } virtual bool HandleFind(const string& cmd UNUSED, const FindCommand& fc, - string* out) override { + const Loc& loc, string* out) override { if (!CanHandle(fc.chdir)) { LOG("FindEmulator: Cannot handle chdir (%.*s): %s", SPF(fc.chdir), cmd.c_str()); @@ -793,6 +793,9 @@ class FindEmulatorImpl : public FindEmulator { 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; @@ -823,9 +826,8 @@ class FindEmulatorImpl : public FindEmulator { if (should_fallback) return false; if (!fc.redirect_to_devnull) { - fprintf(stderr, - "FindEmulator: cd: %.*s: No such file or directory\n", - SPF(fc.chdir)); + WARN_LOC(loc, "FindEmulator: cd: %.*s: No such file or directory", + SPF(fc.chdir)); } return true; } @@ -848,16 +850,15 @@ class FindEmulatorImpl : public FindEmulator { return false; } if (!fc.redirect_to_devnull) { - fprintf(stderr, - "FindEmulator: find: `%s': No such file or directory\n", - ConcatDir(fc.chdir, finddir).c_str()); + WARN_LOC(loc, "FindEmulator: find: `%s': No such file or directory", + ConcatDir(fc.chdir, finddir).c_str()); } continue; } string path = finddir; unordered_map<const DirentNode*, string> cur_read_dirs; - if (!base->RunFind(fc, 0, &path, &cur_read_dirs, results)) { + if (!base->RunFind(fc, loc, 0, &path, &cur_read_dirs, results)) { LOG("FindEmulator: RunFind failed: %s", cmd.c_str()); return false; } @@ -916,8 +917,14 @@ class FindEmulatorImpl : public FindEmulator { 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); @@ -942,6 +949,9 @@ class FindEmulatorImpl : public FindEmulator { } 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)); @@ -994,7 +1004,12 @@ class FindEmulatorImpl : public FindEmulator { 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)); |
