void CSimulation2Impl::DumpState() { PROFILE("DumpState"); std::stringstream pid; pid << getpid(); std::stringstream name;\ name << std::setw(5) << std::setfill('0') << m_TurnNumber << ".txt"; OsPath path = psLogDir() / "sim_log" / pid.str() / name.str(); CreateDirectories(path.Parent(), 0700); std::ofstream file (OsString(path).c_str(), std::ofstream::out | std::ofstream::trunc); file << "State hash: " << std::hex; std::string hashRaw; m_ComponentManager.ComputeStateHash(hashRaw, false); for (size_t i = 0; i < hashRaw.size(); ++i) file << std::setfill('0') << std::setw(2) << (int)(unsigned char)hashRaw[i]; file << std::dec << "\n"; file << "\n"; m_ComponentManager.DumpDebugState(file, true); std::ofstream binfile (OsString(path.ChangeExtension(L".dat")).c_str(), std::ofstream::out | std::ofstream::trunc | std::ofstream::binary); m_ComponentManager.SerializeState(binfile); }
void CNetTurnManager::OnSyncError(u32 turn, const std::string& expectedHash) { NETTURN_LOG((L"OnSyncError(%d, %ls)\n", turn, Hexify(expectedHash).c_str())); // Only complain the first time if (m_HasSyncError) return; m_HasSyncError = true; bool quick = !TurnNeedsFullHash(turn); std::string hash; bool ok = m_Simulation2.ComputeStateHash(hash, quick); ENSURE(ok); OsPath path = psLogDir()/"oos_dump.txt"; std::ofstream file (OsString(path).c_str(), std::ofstream::out | std::ofstream::trunc); m_Simulation2.DumpDebugState(file); file.close(); std::wstringstream msg; msg << L"Out of sync on turn " << turn << L": expected hash " << Hexify(expectedHash) << L"\n\n"; msg << L"Current state: turn " << m_CurrentTurn << L", hash " << Hexify(hash) << L"\n\n"; msg << L"Dumping current state to " << path; g_GUI->DisplayMessageBox(600, 350, L"Sync error", msg.str()); }
FSEventStreamRef CreateEventStream( DirWatchMap path ) { if ( ( g_Stream == NULL ) && CanRunNotifications() ) { CFStringRef* pathLists = (CFStringRef*)malloc( sizeof(CFStringRef*) * path.size() ); int index = 0; for ( DirWatchMap::iterator it = path.begin() ; it != path.end(); ++it) { pathLists[index] = CFStringCreateWithFileSystemRepresentation( NULL, OsString(it->path).c_str()); index++; } CFArrayRef pathsToWatch = CFArrayCreate(NULL, (const void **)pathLists, index, NULL); FSEventStreamContext *callbackInfo = NULL; FSEventStreamRef stream = FSEventStreamCreate(NULL, &fsevent_callback, callbackInfo, pathsToWatch, kFSEventStreamEventIdSinceNow, 1.0, kFSEventStreamCreateFlagFileEvents ); CFRelease( pathsToWatch ); free( pathLists ); FSEventStreamScheduleWithRunLoop(stream, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode); if (!FSEventStreamStart(stream)) debug_warn(L"event_loop FSEventStreamStart failed!"); else return stream; } return NULL; }
void CProfileViewer::SaveToFile() { // Open the file, if necessary. If this method is called several times, // the profile results will be appended to the previous ones from the same // run. if (! m->outputStream.is_open()) { // Open the file. (It will be closed when the CProfileViewer // destructor is called.) OsPath path = psLogDir()/"profile.txt"; m->outputStream.open(OsString(path).c_str(), std::ofstream::out | std::ofstream::trunc); if (m->outputStream.fail()) { LOGERROR(L"Failed to open profile log file"); return; } else { LOGMESSAGERENDER(L"Profiler snapshot saved to '%ls'", path.string().c_str()); } } time_t t; time(&t); m->outputStream << "================================================================\n\n"; m->outputStream << "PS profiler snapshot - " << asctime(localtime(&t)); std::vector<AbstractProfileTable*> tables = m->rootTables; sort(tables.begin(), tables.end(), SortByName); for_each(tables.begin(), tables.end(), WriteTable(m->outputStream)); m->outputStream << "\n\n================================================================\n"; m->outputStream.flush(); }
void CProfiler2::SaveToFile() { OsPath path = psLogDir()/"profile2.jsonp"; std::ofstream stream(OsString(path).c_str(), std::ofstream::out | std::ofstream::trunc); ENSURE(stream.good()); std::vector<ThreadStorage*> threads; { CScopeLock lock(m_Mutex); threads = m_Threads; } stream << "profileDataCB({\"threads\": [\n"; for (size_t i = 0; i < threads.size(); ++i) { if (i != 0) stream << ",\n"; stream << "{\"name\":\"" << CStr(threads[i]->GetName()).EscapeToPrintableASCII() << "\",\n"; stream << "\"data\": "; ConstructJSONResponse(stream, threads[i]->GetName()); stream << "\n}"; } stream << "\n]});\n"; }
void CReplayLogger::StartGame(JS::MutableHandleValue attribs) { // Add timestamp, since the file-modification-date can change m_ScriptInterface.SetProperty(attribs, "timestamp", std::to_string(std::time(nullptr))); // Add engine version and currently loaded mods for sanity checks when replaying m_ScriptInterface.SetProperty(attribs, "engine_version", CStr(engine_version)); m_ScriptInterface.SetProperty(attribs, "mods", g_modsLoaded); // Construct the directory name based on the PID, to be relatively unique. // Append "-1", "-2" etc if we run multiple matches in a single session, // to avoid accidentally overwriting earlier logs. static int run = -1; do { std::wstringstream name; name << getpid(); if (++run) name << "-" << run; m_Directory = psLogDir() / L"sim_log" / name.str(); } while (DirectoryExists(m_Directory)); CreateDirectories(m_Directory, 0700); m_Stream = new std::ofstream(OsString(m_Directory / L"commands.txt").c_str(), std::ofstream::out | std::ofstream::trunc); *m_Stream << "start " << m_ScriptInterface.StringifyJSON(attribs, false) << "\n"; }
OsPath wrealpath(const OsPath& pathname) { char resolvedBuf[PATH_MAX]; const char* resolved = realpath(OsString(pathname).c_str(), resolvedBuf); if(!resolved) return OsPath(); return resolved; }
static void StartDriver(const OsPath& driverPathname) { const SC_HANDLE hSCM = OpenServiceControlManager(); if(!hSCM) { ENSURE(GetLastError() == ERROR_ACCESS_DENIED); SetLastError(0); return; } SC_HANDLE hService = OpenServiceW(hSCM, AKEN_NAME, SERVICE_ALL_ACCESS); // during development, we want to ensure the newest build is used, so // unload and re-create the service if it's running/installed. // as of 2008-03-24 no further changes to Aken are pending, so this is // disabled (thus also avoiding trouble when running multiple instances) #if 0 if(hService) { BOOL ok = CloseServiceHandle(hService); WARN_IF_FALSE(ok); hService = 0; UninstallDriver(); } #endif // create service (note: this just enters the service into SCM's DB; // no error is raised if the driver binary doesn't exist etc.) if(!hService) { LPCWSTR startName = 0; // LocalSystem // NB: Windows 7 seems to insist upon backslashes (i.e. external_file_string) hService = CreateServiceW(hSCM, AKEN_NAME, AKEN_NAME, SERVICE_ALL_ACCESS, SERVICE_KERNEL_DRIVER, SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL, OsString(driverPathname).c_str(), 0, 0, 0, startName, 0); ENSURE(hService != 0); } // start service { DWORD numArgs = 0; BOOL ok = StartService(hService, numArgs, 0); if(!ok) { if(GetLastError() != ERROR_SERVICE_ALREADY_RUNNING) { // starting failed. don't raise a warning because this // always happens on least-permission user accounts. //DEBUG_WARN_ERR(ERR::LOGIC); } } } CloseServiceHandle(hService); CloseServiceHandle(hSCM); }
void CSimulation2Impl::DumpSerializationTestState(SerializationTestState& state, const OsPath& path, const OsPath::String& suffix) { if (!state.hash.empty()) { std::ofstream file (OsString(path / (L"hash." + suffix)).c_str(), std::ofstream::out | std::ofstream::trunc); file << Hexify(state.hash); } if (!state.debug.str().empty()) { std::ofstream file (OsString(path / (L"debug." + suffix)).c_str(), std::ofstream::out | std::ofstream::trunc); file << state.debug.str(); } if (!state.state.str().empty()) { std::ofstream file (OsString(path / (L"state." + suffix)).c_str(), std::ofstream::out | std::ofstream::trunc | std::ofstream::binary); file << state.state.str(); } }
WDIR* wopendir(const OsPath& path) { init_libc(); DIR* d = opendir(OsString(path).c_str()); if(!d) return 0; WDIR* wd = new WDIR; wd->d = d; wd->name[0] = '\0'; wd->ent.d_name = wd->name; return wd; }
static Status ReadVersionString(const OsPath& modulePathname, wchar_t* out_ver, size_t out_ver_len) { WinScopedPreserveLastError s; // GetFileVersion*, Ver* // determine size of and allocate memory for version information. DWORD unused; const DWORD ver_size = GetFileVersionInfoSizeW(OsString(modulePathname).c_str(), &unused); // [bytes] if(!ver_size) { // check if the failure is due to not finding modulePathname // (necessary since GetFileVersionInfoSize doesn't SetLastError) HMODULE hModule = LoadLibraryExW(OsString(modulePathname).c_str(), 0, LOAD_LIBRARY_AS_DATAFILE); if(!hModule) return ERR::FAIL; // NOWARN (file not found - due to FS redirection?) FreeLibrary(hModule); return ERR::NOT_SUPPORTED; // NOWARN (module apparently lacks version information) } shared_ptr<u8> mem = Allocate(ver_size); if(!GetFileVersionInfoW(OsString(modulePathname).c_str(), 0, ver_size, mem.get())) WARN_RETURN(ERR::_3); u16* lang; // -> 16 bit language ID, 16 bit codepage UINT lang_len; const BOOL ok = VerQueryValueW(mem.get(), L"\\VarFileInfo\\Translation", (void**)&lang, &lang_len); if(!ok || !lang || lang_len != 4) WARN_RETURN(ERR::_4); wchar_t subblock[64]; swprintf_s(subblock, ARRAY_SIZE(subblock), L"\\StringFileInfo\\%04X%04X\\FileVersion", lang[0], lang[1]); const wchar_t* in_ver; UINT in_ver_len; if(!VerQueryValueW(mem.get(), subblock, (void**)&in_ver, &in_ver_len)) WARN_RETURN(ERR::_5); wcscpy_s(out_ver, out_ver_len, in_ver); return INFO::OK; }
void ScriptTestSetup(ScriptInterface& ifc) { ifc.RegisterFunction<void, std::wstring, script_TS_FAIL>("TS_FAIL"); // Load the TS_* function definitions // (We don't use VFS because tests might not have the normal VFS paths loaded) OsPath path = DataDir()/"tests"/"test_setup.js"; std::ifstream ifs(OsString(path).c_str()); ENSURE(ifs.good()); std::string content((std::istreambuf_iterator<char>(ifs)), std::istreambuf_iterator<char>()); std::wstring wcontent(content.begin(), content.end()); bool ok = ifc.LoadScript(L"test_setup.js", wcontent); ENSURE(ok); }
static Status OpenFile(const OsPath& pathname, int oflag, HANDLE& hFile) { WinScopedPreserveLastError s; const DWORD access = DesiredAccess(oflag); const DWORD share = ShareMode(oflag); const DWORD create = CreationDisposition(oflag); const DWORD flags = FlagsAndAttributes(); hFile = CreateFileW(OsString(pathname).c_str(), access, share, 0, create, flags, 0); if(hFile == INVALID_HANDLE_VALUE) WARN_RETURN(StatusFromWin()); return INFO::OK; }
Status dir_watch_Add(const OsPath& path, PDirWatch& dirWatch) { char resolved[PATH_MAX + 1]; // init already failed; don't try again or complain if(initialized == -1) return ERR::FAIL; // NOWARN if(!initialized) { errno = 0; if((inotifyfd = inotify_init()) < 0) { // Check for error ? int err = errno; initialized = -1; LOGERROR("Error initializing inotify file descriptor; hotloading will be disabled, errno=%d", err); errno = err; return StatusFromErrno(); // NOWARN } errno = 0; int ret = pthread_create(&g_event_loop_thread, NULL, &inotify_event_loop, NULL); if (ret != 0) { initialized = -1; LOGERROR("Error creating inotify event loop thread; hotloading will be disabled, err=%d", ret); errno = ret; return StatusFromErrno(); // NOWARN } initialized = 1; atexit(inotify_deinit); } PDirWatch tmpDirWatch(new DirWatch); errno = 0; int wd = inotify_add_watch(inotifyfd, realpath(OsString(path).c_str(), resolved), IN_CREATE | IN_DELETE | IN_CLOSE_WRITE); if (wd < 0) WARN_RETURN(StatusFromErrno()); dirWatch.swap(tmpDirWatch); dirWatch->path = path; dirWatch->reqnum = wd; g_paths.insert(std::make_pair(wd, dirWatch)); return INFO::OK; }
Status dir_watch_Poll(DirWatchNotifications& notifications) { if(initialized == -1) return ERR::FAIL; // NOWARN if(!initialized) // XXX Fix Atlas instead of suppressing the warning return ERR::FAIL; //WARN_RETURN(ERR::LOGIC); std::vector<NotificationEvent> polled_notifications; pthread_mutex_lock(&g_mutex); g_notifications.swap(polled_notifications); pthread_mutex_unlock(&g_mutex); for(size_t i = 0; i < polled_notifications.size(); ++i) { DirWatchNotification::EType type; // TODO: code is actually a bitmask, so this is slightly incorrect switch(polled_notifications[i].code) { case IN_CLOSE_WRITE: type = DirWatchNotification::Changed; break; case IN_CREATE: type = DirWatchNotification::Created; break; case IN_DELETE: type = DirWatchNotification::Deleted; break; default: continue; } DirWatchMap::iterator it = g_paths.find(polled_notifications[i].wd); if(it != g_paths.end()) { OsPath filename = Path(OsString(it->second->path).append(polled_notifications[i].filename)); notifications.push_back(DirWatchNotification(filename, type)); } else { debug_printf("dir_watch_Poll: Notification with invalid watch descriptor wd=%d\n", polled_notifications[i].wd); } } // nothing new; try again later return INFO::OK; }
CReplayLogger::CReplayLogger(ScriptInterface& scriptInterface) : m_ScriptInterface(scriptInterface) { // Construct the directory name based on the PID, to be relatively unique. // Append "-1", "-2" etc if we run multiple matches in a single session, // to avoid accidentally overwriting earlier logs. std::wstringstream name; name << getpid(); static int run = -1; if (++run) name << "-" << run; OsPath path = psLogDir() / L"sim_log" / name.str() / L"commands.txt"; CreateDirectories(path.Parent(), 0700); m_Stream = new std::ofstream(OsString(path).c_str(), std::ofstream::out | std::ofstream::trunc); }
void CNetTurnManager::OnSyncError(u32 turn, const CStr& expectedHash, std::vector<CSyncErrorMessage::S_m_PlayerNames>& playerNames) { NETTURN_LOG((L"OnSyncError(%d, %hs)\n", turn, Hexify(expectedHash).c_str())); // Only complain the first time if (m_HasSyncError) return; bool quick = !TurnNeedsFullHash(turn); std::string hash; ENSURE(m_Simulation2.ComputeStateHash(hash, quick)); OsPath path = psLogDir()/"oos_dump.txt"; std::ofstream file (OsString(path).c_str(), std::ofstream::out | std::ofstream::trunc); m_Simulation2.DumpDebugState(file); file.close(); hash = Hexify(hash); const std::string& expectedHashHex = Hexify(expectedHash); DisplayOOSError(turn, hash, expectedHashHex, false, &playerNames, &path); }
FILE* sys_OpenFile(const OsPath& pathname, const char* mode) { return fopen(OsString(pathname).c_str(), mode); }
int wrename(const OsPath& pathnameOld, const OsPath& pathnameNew) { return rename(OsString(pathnameOld).c_str(), OsString(pathnameNew).c_str()); }
int wtruncate(const OsPath& pathname, off_t length) { return truncate(OsString(pathname).c_str(), length); }
int wstat(const OsPath& pathname, struct stat* buf) { return stat(OsString(pathname).c_str(), buf); }
void RDSvc::setPreimportCommand(ImportSource src,ImportOs os, const QString &path) const { QString fieldname=SourceString(src)+OsString(os)+"PREIMPORT_CMD"; SetRow(fieldname,path); }
QString RDSvc::preimportCommand(ImportSource src,ImportOs os) const { QString fieldname=SourceString(src)+OsString(os)+"PREIMPORT_CMD"; return RDGetSqlValue("SERVICES","NAME",svc_name,fieldname). toString(); }
void RDSvc::setImportPath(ImportSource src,ImportOs os,const QString &path) const { QString fieldname=SourceString(src)+OsString(os)+"PATH"; SetRow(fieldname,path); }
int wrmdir(const OsPath& path) { return rmdir(OsString(path).c_str()); }
int wmkdir(const OsPath& path, mode_t mode) { return mkdir(OsString(path).c_str(), mode); }
int wopen(const OsPath& pathname, int oflag, mode_t mode) { return open(OsString(pathname).c_str(), oflag, mode); }
int wunlink(const OsPath& pathname) { return unlink(OsString(pathname).c_str()); }
QString RDSvc::importPath(ImportSource src,ImportOs os) const { QString fieldname=SourceString(src)+OsString(os)+"PATH"; return RDGetSqlValue("SERVICES","NAME",svc_name,fieldname). toString(); }
int wopen(const OsPath& pathname, int oflag) { ENSURE(!(oflag & O_CREAT)); return open(OsString(pathname).c_str(), oflag); }