void Repo::initCentral() { std::vector<std::string> failPaths; assert(m_dbc == nullptr); // Try Repo.Central.Path (or HHVM_REPO_CENTRAL_PATH). if (!RuntimeOption::RepoCentralPath.empty()) { if (!openCentral(RuntimeOption::RepoCentralPath.c_str())) { return; } failPaths.push_back(RuntimeOption::RepoCentralPath); } const char* HHVM_REPO_CENTRAL_PATH = getenv("HHVM_REPO_CENTRAL_PATH"); if (HHVM_REPO_CENTRAL_PATH != nullptr) { if (!openCentral(HHVM_REPO_CENTRAL_PATH)) { return; } failPaths.push_back(HHVM_REPO_CENTRAL_PATH); } // Try "$HOME/.hhvm.hhbc". char* HOME = getenv("HOME"); if (HOME != nullptr) { std::string centralPath = HOME; centralPath += "/.hhvm.hhbc"; if (!openCentral(centralPath.c_str())) { return; } failPaths.push_back(centralPath); } // Try the equivalent of "$HOME/.hhvm.hhbc", but look up the home directory // in the password database. { struct passwd pwbuf; struct passwd* pwbufp; long bufsize = sysconf(_SC_GETPW_R_SIZE_MAX); if (bufsize != -1) { char buf[size_t(bufsize)]; if (!getpwuid_r(getuid(), &pwbuf, buf, size_t(bufsize), &pwbufp) && (HOME == nullptr || strcmp(HOME, pwbufp->pw_dir))) { std::string centralPath = pwbufp->pw_dir; centralPath += "/.hhvm.hhbc"; if (!openCentral(centralPath.c_str())) { return; } failPaths.push_back(centralPath); } } } // Database initialization failed; this is an unrecoverable state. for (std::vector<std::string>::const_iterator it = failPaths.begin(); it != failPaths.end(); ++it) { Logger::Error("Failed to initialize central HHBC repository at '%s'", (*it).c_str()); } exit(1); }
void Repo::initCentral() { std::string error; assert(m_dbc == nullptr); auto tryPath = [this, &error](const char* path) { std::string subErr; if (!openCentral(path, subErr)) { folly::format(&error, " {}\n", subErr.empty() ? path : subErr); return false; } return true; }; // Try Repo.Central.Path if (!RuntimeOption::RepoCentralPath.empty()) { if (tryPath(RuntimeOption::RepoCentralPath.c_str())) { return; } } // Try HHVM_REPO_CENTRAL_PATH const char* HHVM_REPO_CENTRAL_PATH = getenv("HHVM_REPO_CENTRAL_PATH"); if (HHVM_REPO_CENTRAL_PATH != nullptr) { if (tryPath(HHVM_REPO_CENTRAL_PATH)) { return; } } // Try "$HOME/.hhvm.hhbc". char* HOME = getenv("HOME"); if (HOME != nullptr) { std::string centralPath = HOME; centralPath += "/.hhvm.hhbc"; if (tryPath(centralPath.c_str())) { return; } } #ifndef _WIN32 // Try the equivalent of "$HOME/.hhvm.hhbc", but look up the home directory // in the password database. { struct passwd pwbuf; struct passwd* pwbufp; long bufsize = sysconf(_SC_GETPW_R_SIZE_MAX); if (bufsize != -1) { auto buf = new char[bufsize]; SCOPE_EXIT { delete[] buf; }; if (!getpwuid_r(getuid(), &pwbuf, buf, size_t(bufsize), &pwbufp) && (HOME == nullptr || strcmp(HOME, pwbufp->pw_dir))) { std::string centralPath = pwbufp->pw_dir; centralPath += "/.hhvm.hhbc"; if (tryPath(centralPath.c_str())) { return; } } } }
void Repo::initCentral() { std::string error; assert(m_dbc == nullptr); auto tryPath = [this, &error](const char* path) { std::string subErr; if (openCentral(path, subErr) == RepoStatus::error) { folly::format(&error, " {}\n", subErr.empty() ? path : subErr); return false; } return true; }; auto fail_no_repo = [&error] { error = "Failed to initialize central HHBC repository:\n" + error; // Database initialization failed; this is an unrecoverable state. Logger::Error("%s", error.c_str()); if (Process::IsInMainThread()) { exit(1); } always_assert_flog(false, "{}", error); }; // Try Repo.Central.Path if (!RuntimeOption::RepoCentralPath.empty() && tryPath(RuntimeOption::RepoCentralPath.c_str())) { return; } // Try HHVM_REPO_CENTRAL_PATH const char* HHVM_REPO_CENTRAL_PATH = getenv("HHVM_REPO_CENTRAL_PATH"); if (HHVM_REPO_CENTRAL_PATH != nullptr && tryPath(HHVM_REPO_CENTRAL_PATH)) { return; } if (!RuntimeOption::RepoAllowFallbackPath) fail_no_repo(); // Try "$HOME/.hhvm.hhbc". char* HOME = getenv("HOME"); if (HOME != nullptr) { std::string centralPath = HOME; centralPath += "/.hhvm.hhbc"; if (tryPath(centralPath.c_str())) { return; } } #ifndef _WIN32 // Try the equivalent of "$HOME/.hhvm.hhbc", but look up the home directory // in the password database. { passwd pwbuf; passwd* pwbufp; long bufsize = sysconf(_SC_GETPW_R_SIZE_MAX); if (bufsize != -1) { auto buf = new char[bufsize]; SCOPE_EXIT { delete[] buf; }; if (!getpwuid_r(getuid(), &pwbuf, buf, size_t(bufsize), &pwbufp) && (HOME == nullptr || strcmp(HOME, pwbufp->pw_dir))) { std::string centralPath = pwbufp->pw_dir; centralPath += "/.hhvm.hhbc"; if (tryPath(centralPath.c_str())) { return; } } } }
void Repo::initCentral() { std::vector<std::string> failPaths; assert(m_dbc == nullptr); // Try Repo.Central.Path (or HHVM_REPO_CENTRAL_PATH). if (!RuntimeOption::RepoCentralPath.empty()) { if (!openCentral(RuntimeOption::RepoCentralPath.c_str())) { return; } failPaths.push_back(RuntimeOption::RepoCentralPath); } const char* HHVM_REPO_CENTRAL_PATH = getenv("HHVM_REPO_CENTRAL_PATH"); if (HHVM_REPO_CENTRAL_PATH != nullptr) { if (!openCentral(HHVM_REPO_CENTRAL_PATH)) { return; } failPaths.push_back(HHVM_REPO_CENTRAL_PATH); } // Try "$HOME/.hhvm.hhbc". char* HOME = getenv("HOME"); if (HOME != nullptr) { std::string centralPath = HOME; centralPath += "/.hhvm.hhbc"; if (!openCentral(centralPath.c_str())) { return; } failPaths.push_back(centralPath); } // Try the equivalent of "$HOME/.hhvm.hhbc", but look up the home directory // in the password database. { struct passwd pwbuf; struct passwd* pwbufp; long bufsize = sysconf(_SC_GETPW_R_SIZE_MAX); if (bufsize != -1) { char buf[size_t(bufsize)]; if (!getpwuid_r(getuid(), &pwbuf, buf, size_t(bufsize), &pwbufp) && (HOME == nullptr || strcmp(HOME, pwbufp->pw_dir))) { std::string centralPath = pwbufp->pw_dir; centralPath += "/.hhvm.hhbc"; if (!openCentral(centralPath.c_str())) { return; } failPaths.push_back(centralPath); } } } // Database initialization failed; this is an unrecoverable state. for (auto const& p : failPaths) { Logger::Error("Failed to initialize central HHBC repository at '%s'", p.c_str()); } // TODO(#3518905): this fails in practice sometimes if file // descriptor limits are too low, which is why the assertion // suggests that. But we should restructure this code so we know // here why each failPath failed and can log the real reasons // instead of guessing. always_assert(!"Failed to connect to HHBC repo (possibly " "out of file descriptors?); aborting"); }