ShellHandler::ShellHandler( shared_ptr<ServiceAuthState> serviceAuthState, apache::thrift::server::TConnectionContext* ctx) : AuthHandler(move(serviceAuthState), ctx) { cwd_ = open(".", O_RDONLY); if (cwd_ < 0) { PLOG(ERROR) << "failed to open current directory"; throwErrno("failed to open current directory"); } }
void ShellHandler::chdir(const string& dir) { unique_lock<mutex> g(mutex_); validateState(); FdGuard newCwd(openat(cwd_, dir.c_str(), O_RDONLY)); if (newCwd < 0) { throwErrno("unable to change directory"); } close(cwd_); cwd_ = newCwd.release(); }
std::string readline(FILE* f) { char* line = nullptr; size_t mx = 0; ssize_t len = 0; SCOPE_EXIT { free(line); }; if ((len = getline(&line, &mx, f)) < 0) { throwErrno("error reading line"); } return len ? std::string(line, len - 1) : std::string(); }
DumpReader::DumpReader(const std::string &dump) : m_dump(0), m_bz(0), m_dumpSize(0), m_bzStatus(BZ_OK) { m_dump = fopen(dump.c_str(), "r"); if (!m_dump) { throwErrno(); } int status; m_bz = BZ2_bzReadOpen(&status, m_dump, 0, 0, 0, 0); if (status) { throw std::logic_error("bzip error"); } if (fseek(m_dump, 0, SEEK_END) || -1 == (m_dumpSize = ftell(m_dump)) || fseek(m_dump, 0, SEEK_SET)) { throwErrno(); } }
void ShellHandler::pwd(string& _return) { unique_lock<mutex> g(mutex_); validateState(); // TODO: this only works on linux char procPath[1024]; snprintf(procPath, sizeof(procPath), "/proc/self/fd/%d", cwd_); char cwdPath[1024]; ssize_t numBytes = readlink(procPath, cwdPath, sizeof(cwdPath)); if (numBytes < 0) { throwErrno("failed to determine current working directory"); } _return.assign(cwdPath, numBytes); }
std::string ExternCompiler::readResult(StructuredLogEntry* log) const { const auto line = readline(m_out); const auto header = folly::parseJson(line); const std::string type = header.getDefault("type", "").asString(); const std::size_t bytes = header.getDefault("bytes", 0).asInt(); const auto logResult = [&] (auto name, auto t) { if (log != nullptr) log->setInt(name, t); FTRACE(2, "{} took {} us\n", name, t); }; if (RuntimeOption::EvalLogExternCompilerPerf) { if (auto parsing_time = header.get_ptr("parsing_time")) { logResult("extern_parsing", parsing_time->asInt()); } if (auto codegen_time = header.get_ptr("codegen_time")) { logResult("extern_codegen", codegen_time->asInt()); } if (auto printing_time = header.get_ptr("printing_time")) { logResult("extern_printing", printing_time->asInt()); } } if (type == "success") { std::string program(bytes, '\0'); if (bytes != 0 && fread(&program[0], bytes, 1, m_out) != 1) { throwErrno("reading input program"); } return program; } else if (type == "error") { // We don't need to restart the pipe -- the compiler just wasn't able to // build this file... throw CompilerFatal( header.getDefault("error", "[no 'error' field]").asString()); } else { throw CompilerFatal("unknown message type, " + type); } not_reached(); }
std::string ExternCompiler::readProgram() const { const auto line = readline(m_out); const auto header = folly::parseJson(line); const std::string type = header.getDefault("type", "").asString(); const std::size_t bytes = header.getDefault("bytes", 0).asInt(); if (type == "hhas") { std::string program(bytes, '\0'); if (fread(&program[0], bytes, 1, m_out) != 1) { throwErrno("reading input program"); } return program; } else if (type == "error") { // We don't need to restart the pipe -- the compiler just wasn't able to // build this file... throw std::runtime_error( header.getDefault("error", "[no 'error' field]").asString()); } else { throw std::runtime_error("unknown message type, " + type); } not_reached(); }