void CmdBase::PrintUsage(const Args& args, Str::StringRef syntax, Str::StringRef description) const { if(description.empty()) { Print("%s: %s %s", _("usage"), args.Argv(0).c_str(), syntax.c_str()); } else { Print("%s: %s %s — %s", _("usage"), args.Argv(0).c_str(), syntax.c_str(), description.c_str()); } }
//TODO: error handling? int VMBase::Create(Str::StringRef name, Type type) { if (module) { Com_Printf(S_ERROR "Attempting to re-create an already-loaded VM"); return -1; } const std::string& libPath = FS::GetLibPath(); bool debug = Cvar_Get("vm_debug", "0", CVAR_INIT)->integer; if (type == TYPE_NATIVE) { std::string exe = FS::Path::Build(libPath, name + EXE_EXT); Com_Printf("Trying to load native module %s\n", exe.c_str()); module = NaCl::LoadModule(exe.c_str(), nullptr, debug); } else if (type == TYPE_NACL) { // Extract the nexe from the pak so that sel_ldr can load it std::string nexe = name + "-" ARCH_STRING ".nexe"; try { FS::File out = FS::HomePath::OpenWrite(nexe); FS::PakPath::CopyFile(nexe, out); out.Close(); } catch (std::system_error& err) { Com_Printf(S_ERROR "Failed to extract NaCl module %s: %s\n", nexe.c_str(), err.what()); return -1; } std::string sel_ldr = FS::Path::Build(libPath, "sel_ldr" EXE_EXT); std::string irt = FS::Path::Build(libPath, "irt_core-" ARCH_STRING ".nexe"); #ifdef __linux__ std::string bootstrap = FS::Path::Build(libPath, "nacl_helper_bootstrap"); NaCl::LoaderParams params = {sel_ldr.c_str(), irt.c_str(), bootstrap.c_str()}; #else NaCl::LoaderParams params = {sel_ldr.c_str(), irt.c_str(), nullptr}; #endif Com_Printf("Trying to load NaCl module %s\n", nexe.c_str()); module = NaCl::LoadModule(FS::Path::Build(FS::GetHomePath(), nexe).c_str(), ¶ms, debug); } else { Com_Printf(S_ERROR "Invalid VM type"); return -1; } if (!module) { Com_Printf(S_ERROR "Couldn't load VM %s", name.c_str()); return -1; } if (debug) Com_Printf("Waiting for GDB connection on localhost:4014\n"); // Read the ABI version from the root socket. // If this fails, we assume the remote process failed to start std::vector<char> buffer; if (!module.GetRootSocket().RecvMsg(buffer) || buffer.size() != sizeof(int)) { Com_Printf(S_ERROR "The '%s' VM did not start.", name.c_str()); return -1; } Com_Printf("Loaded module with the NaCl ABI"); return *reinterpret_cast<int*>(buffer.data()); }
intptr_t DynamicLib::InternalLoadSym(Str::StringRef sym, std::string& errorString) { #ifdef _WIN32 intptr_t p = reinterpret_cast<intptr_t>( GetProcAddress(static_cast<HMODULE>(handle), sym.c_str())); if (!p) errorString = Win32StrError(GetLastError()); return p; #else intptr_t p = reinterpret_cast<intptr_t>(dlsym(handle, sym.c_str())); if (!p) errorString = dlerror(); return p; #endif }
void Rocket_AddConsoleText(Str::StringRef text) { // HACK: Ugly way to force pre-engine-upgrade behavior. TODO: Make it work without this hack static char buffer[ MAX_STRING_CHARS ]; Q_strncpyz( buffer, text.c_str(), sizeof(buffer) ); if ( !Q_stricmp( "\n", buffer ) ) { return; } RocketConsoleTextElement::lines.push_front( ConsoleLine( Rocket::Core::String( va( "%s\n", buffer ) ) ) ); }
void Drop(Str::StringRef message) { // Transform into a fatal error if too many errors are generated in quick // succession. static Sys::SteadyClock::time_point lastError; Sys::SteadyClock::time_point now = Sys::SteadyClock::now(); static int errorCount = 0; if (now - lastError < std::chrono::milliseconds(100)) { if (++errorCount > 3) Sys::Error(message); } else errorCount = 0; lastError = now; throw DropErr(message.c_str()); }
DynamicLib DynamicLib::Open(Str::StringRef filename, std::string& errorString) { #ifdef _WIN32 void* handle = LoadLibraryW(Str::UTF8To16(filename).c_str()); if (!handle) errorString = Win32StrError(GetLastError()); #else // Handle relative paths correctly const char* dlopenFilename = filename.c_str(); std::string relativePath; if (filename.find('/') == std::string::npos) { relativePath = "./" + filename; dlopenFilename = relativePath.c_str(); } void* handle = dlopen(dlopenFilename, RTLD_NOW); if (!handle) errorString = dlerror(); #endif DynamicLib out; out.handle = handle; return out; }