bool resolveLink(const bfs::path& path, bfs::path& target) { bool rval = false; int cfd = -1; bfs::path linkVal = readLink(path); try { if (!linkVal.empty()) { bfs::path parent = path.parent_path(); if (!parent.empty()) { cfd = ::open(".", O_RDONLY, 0); if (cfd < 0) { throw string("unable to open ."); } if (::chdir(parent.c_str()) < 0) { throw string("unable to chdir to ") + parent.c_str(); } } char buf[PATH_MAX+1]; if (::realpath(path.c_str(), buf) == NULL) { throw string("realpath failed"); } target = buf; rval = pathExists(target); } } catch (const string&) { rval = false; } if (!rval) { target.clear(); } if (cfd >= 0) { ::fchdir(cfd); ::close(cfd); } return rval; }
/** \todo Introduce a tree structure to improve the efficiency of searching matched directories */ bool ParametricPathProcessorImpl::findSubDirectoryOfDirectoryVariable (const filesystem::path& path, std::string& out_varName, filesystem::path& out_relativePath) { out_relativePath.clear(); int maxMatchSize = 0; filesystem::path relativePath; Mapping::const_iterator p; for(p = variables->begin(); p != variables->end(); ++p){ Listing* paths = p->second->toListing(); if(paths){ for(int i=0; i < paths->size(); ++i){ filesystem::path dirPath(paths->at(i)->toString()); int n = findSubDirectory(dirPath, path, relativePath); if(n > maxMatchSize){ maxMatchSize = n; out_relativePath = relativePath; out_varName = fromUTF8(p->first); } } } } return (maxMatchSize > 0); }