SNAP Library 2.2, User Reference
2014-03-11 19:15:55
SNAP, a general purpose, high performance system for analysis and manipulation of large networks
|
00001 #ifdef GLib_WIN 00002 00004 // System-Processes 00005 void TSysProc::Sleep(const uint& MSecs){ 00006 SleepEx(MSecs, false); 00007 } 00008 00009 TStr TSysProc::GetExeFNm(){ 00010 DWORD MxFNmLen=1024; 00011 LPTSTR FNmCStr=new char[MxFNmLen]; 00012 DWORD FNmLen=GetModuleFileName(NULL, FNmCStr, MxFNmLen); 00013 TStr FNm; 00014 if (FNmLen!=0){ 00015 FNm=FNmCStr;} 00016 delete[] FNmCStr; 00017 return FNm; 00018 } 00019 00020 void TSysProc::SetLowPriority(){ 00021 SetPriorityClass(GetCurrentProcess(), IDLE_PRIORITY_CLASS); 00022 } 00023 00024 bool TSysProc::ExeProc(const TStr& ExeFNm, TStr& ParamStr){ 00025 STARTUPINFO si; 00026 PROCESS_INFORMATION pi; 00027 ZeroMemory(&si, sizeof(si)); 00028 si.cb=sizeof(si); 00029 ZeroMemory(&pi, sizeof(pi)); 00030 00031 // Start the child process. 00032 BOOL Ok=CreateProcess( 00033 ExeFNm.CStr(), // module name 00034 ParamStr.CStr(), // patameters 00035 NULL, // Process handle not inheritable. 00036 NULL, // Thread handle not inheritable. 00037 FALSE, // Set handle inheritance to FALSE. 00038 0, // No creation flags. 00039 NULL, // Use parent's environment block. 00040 NULL, // Use parent's starting directory. 00041 &si, // Pointer to STARTUPINFO structure. 00042 &pi); // Pointer to PROCESS_INFORMATION structure. 00043 if (Ok){ 00044 // Wait until child process exits. 00045 WaitForSingleObject( pi.hProcess, INFINITE ); 00046 // Close process and thread handles. 00047 CloseHandle( pi.hProcess ); 00048 CloseHandle( pi.hThread ); 00049 return true; 00050 } else { 00051 return false; 00052 } 00053 } 00054 00056 // Memory-Status 00057 TStr TSysMemStat::GetLoadStr(){ 00058 static TStr MemUsageStr="Mem Load: "; 00059 TChA ChA; 00060 ChA+=MemUsageStr; 00061 ChA+=TUInt64::GetStr(GetLoad()); 00062 ChA+="%"; 00063 return ChA; 00064 } 00065 00066 TStr TSysMemStat::GetUsageStr(){ 00067 static TStr MemUsageStr="Mem Usage: "; 00068 uint64 GlobalUsage=GetTotalPageFile()-GetAvailPageFile(); 00069 TChA ChA; 00070 ChA+=MemUsageStr; 00071 ChA+=TUInt64::GetStr(GlobalUsage/1024); 00072 ChA+="K / "; 00073 ChA+=TUInt64::GetStr(GetTotalPageFile()/1024); 00074 ChA+="K"; 00075 return ChA; 00076 } 00077 00078 TStr TSysMemStat::GetInfoStr(){ 00079 TChA ChA; 00080 ChA+="Memory Load:"; 00081 ChA+=TUInt64::GetMegaStr(GetLoad()); ChA+="\r\n"; 00082 ChA+="Total Physical:"; 00083 ChA+=TUInt64::GetMegaStr(GetTotalPhys()); ChA+="\r\n"; 00084 ChA+="Available Physical:"; 00085 ChA+=TUInt64::GetMegaStr(GetAvailPhys()); ChA+="\r\n"; 00086 ChA+="Total Page File:"; 00087 ChA+=TUInt64::GetMegaStr(GetTotalPageFile()); ChA+="\r\n"; 00088 ChA+="Available Page File:"; 00089 ChA+=TUInt64::GetMegaStr(GetAvailPageFile()); ChA+="\r\n"; 00090 ChA+="Total Virtual:"; 00091 ChA+=TUInt64::GetMegaStr(GetTotalVirtual()); ChA+="\r\n"; 00092 ChA+="Available Virtual:"; 00093 ChA+=TUInt64::GetMegaStr(GetAvailVirtual()); ChA+="\r\n"; 00094 return ChA; 00095 } 00096 00097 TStr TSysMemStat::GetStr(){ 00098 TChA ChA; 00099 ChA+=TUInt64::GetStr(GetLoad()); ChA+=' '; 00100 ChA+=TUInt64::GetStr(GetTotalPhys()); ChA+=' '; 00101 ChA+=TUInt64::GetStr(GetAvailPhys()); ChA+=' '; 00102 ChA+=TUInt64::GetStr(GetTotalPageFile()); ChA+=' '; 00103 ChA+=TUInt64::GetStr(GetAvailPageFile()); ChA+=' '; 00104 ChA+=TUInt64::GetStr(GetTotalVirtual()); ChA+=' '; 00105 ChA+=TUInt64::GetStr(GetAvailVirtual()); 00106 return ChA; 00107 } 00108 00110 // System-Console 00111 TSysConsole::TSysConsole(){ 00112 Ok=(AllocConsole()!=0); 00113 IAssert(Ok); 00114 hStdOut=GetStdHandle(STD_OUTPUT_HANDLE); 00115 IAssert(hStdOut!=INVALID_HANDLE_VALUE); 00116 } 00117 00118 TSysConsole::~TSysConsole(){ 00119 if (Ok){ 00120 IAssert(FreeConsole());} 00121 } 00122 00123 void TSysConsole::Put(const TStr& Str){ 00124 DWORD ChsWritten; 00125 WriteConsole(hStdOut, Str.CStr(), Str.Len(), &ChsWritten, NULL); 00126 IAssert(ChsWritten==DWORD(Str.Len())); 00127 } 00128 00130 // System-Console-Notifier 00131 void TSysConsoleNotify::OnNotify(const TNotifyType& Type, const TStr& MsgStr){ 00132 if (Type==ntInfo){ 00133 SysConsole->PutLn(TStr::Fmt("%s", MsgStr.CStr())); 00134 } else { 00135 TStr TypeStr=TNotify::GetTypeStr(Type, false); 00136 SysConsole->PutLn(TStr::Fmt("%s: %s", TypeStr.CStr(), MsgStr.CStr())); 00137 } 00138 } 00139 00140 void TSysConsoleNotify::OnStatus(const TStr& MsgStr){ 00141 SysConsole->Put(MsgStr.CStr()); 00142 // print '\n' if message not overlayed 00143 if ((!MsgStr.Empty())&&(MsgStr.LastCh()!='\r')){ 00144 SysConsole->PutLn(""); } 00145 } 00146 00148 // System-Messages 00149 //void TSysMsg::Loop(){ 00150 // MSG Msg; 00151 // while (GetMessage(&Msg, NULL, 0, 0 )){ 00152 // TranslateMessage(&Msg); DispatchMessage(&Msg);} 00153 //} 00154 // 00155 //void TSysMsg::Quit(){PostQuitMessage(0);} 00156 00158 // System-Time 00159 TTm TSysTm::GetCurUniTm(){ 00160 SYSTEMTIME SysTm; 00161 GetSystemTime(&SysTm); 00162 return TTm(SysTm.wYear, SysTm.wMonth, SysTm.wDay, SysTm.wDayOfWeek, 00163 SysTm.wHour, SysTm.wMinute, SysTm.wSecond, SysTm.wMilliseconds); 00164 } 00165 00166 TTm TSysTm::GetCurLocTm(){ 00167 SYSTEMTIME SysTm; 00168 GetLocalTime(&SysTm); 00169 return TTm(SysTm.wYear, SysTm.wMonth, SysTm.wDay, SysTm.wDayOfWeek, 00170 SysTm.wHour, SysTm.wMinute, SysTm.wSecond, SysTm.wMilliseconds); 00171 } 00172 00173 uint64 TSysTm::GetCurUniMSecs(){ 00174 SYSTEMTIME SysTm; FILETIME FileTm; 00175 GetSystemTime(&SysTm); 00176 IAssert(SystemTimeToFileTime(&SysTm, &FileTm)); 00177 TUInt64 UInt64(uint(FileTm.dwHighDateTime), uint(FileTm.dwLowDateTime)); 00178 return UInt64.Val/uint64(10000); 00179 } 00180 00181 uint64 TSysTm::GetCurLocMSecs(){ 00182 SYSTEMTIME SysTm; FILETIME FileTm; 00183 GetLocalTime(&SysTm); 00184 IAssert(SystemTimeToFileTime(&SysTm, &FileTm)); 00185 TUInt64 UInt64(uint(FileTm.dwHighDateTime), uint(FileTm.dwLowDateTime)); 00186 return UInt64.Val/uint64(10000); 00187 } 00188 00189 uint64 TSysTm::GetMSecsFromTm(const TTm& Tm){ 00190 SYSTEMTIME SysTm; FILETIME FileTm; 00191 SysTm.wYear=WORD(Tm.GetYear()); 00192 SysTm.wMonth=WORD(Tm.GetMonth()); 00193 SysTm.wDayOfWeek=WORD(Tm.GetDayOfWeek()); 00194 SysTm.wDay=WORD(Tm.GetDay()); 00195 SysTm.wHour=WORD(Tm.GetHour()); 00196 SysTm.wMinute=WORD(Tm.GetMin()); 00197 SysTm.wSecond=WORD(Tm.GetSec()); 00198 SysTm.wMilliseconds=WORD(Tm.GetMSec()); 00199 ESAssert(SystemTimeToFileTime(&SysTm, &FileTm)); 00200 TUInt64 UInt64(uint(FileTm.dwHighDateTime), uint(FileTm.dwLowDateTime)); 00201 return UInt64.Val/uint64(10000); 00202 } 00203 00204 TTm TSysTm::GetTmFromMSecs(const uint64& MSecs){ 00205 TUInt64 FileTmUnits(MSecs*uint64(10000)); 00206 SYSTEMTIME SysTm; FILETIME FileTm; 00207 FileTm.dwHighDateTime=FileTmUnits.GetMsVal(); 00208 FileTm.dwLowDateTime=FileTmUnits.GetLsVal(); 00209 SAssert(FileTimeToSystemTime(&FileTm, &SysTm)); 00210 return TTm(SysTm.wYear, SysTm.wMonth, SysTm.wDay, SysTm.wDayOfWeek, 00211 SysTm.wHour, SysTm.wMinute, SysTm.wSecond, SysTm.wMilliseconds); 00212 } 00213 00214 uint TSysTm::GetMSecsFromOsStart(){ 00215 return uint(GetTickCount()); 00216 } 00217 00218 TTm TSysTm::GetLocTmFromUniTm(const TTm& Tm){ 00219 // get time-zone information 00220 TIME_ZONE_INFORMATION TzInf; 00221 GetTimeZoneInformation(&TzInf); 00222 // get system time 00223 SYSTEMTIME UniSysTm; 00224 UniSysTm.wYear=WORD(Tm.GetYear()); 00225 UniSysTm.wMonth=WORD(Tm.GetMonth()); 00226 UniSysTm.wDayOfWeek=WORD(Tm.GetDayOfWeek()); 00227 UniSysTm.wDay=WORD(Tm.GetDay()); 00228 UniSysTm.wHour=WORD(Tm.GetHour()); 00229 UniSysTm.wMinute=WORD(Tm.GetMin()); 00230 UniSysTm.wSecond=WORD(Tm.GetSec()); 00231 UniSysTm.wMilliseconds=WORD(Tm.GetMSec()); 00232 // convert system-time 00233 SYSTEMTIME LocSysTm; 00234 SystemTimeToTzSpecificLocalTime(&TzInf, &UniSysTm, &LocSysTm); 00235 // return local-time 00236 return TTm(LocSysTm.wYear, LocSysTm.wMonth, LocSysTm.wDay, LocSysTm.wDayOfWeek, 00237 LocSysTm.wHour, LocSysTm.wMinute, LocSysTm.wSecond, LocSysTm.wMilliseconds); 00238 } 00239 00240 TTm TSysTm::GetUniTmFromLocTm(const TTm& Tm){ 00241 // get time-zone information 00242 TIME_ZONE_INFORMATION TzInf; 00243 GetTimeZoneInformation(&TzInf); 00244 // get system time 00245 SYSTEMTIME LocSysTm; 00246 LocSysTm.wYear=WORD(Tm.GetYear()); 00247 LocSysTm.wMonth=WORD(Tm.GetMonth()); 00248 LocSysTm.wDayOfWeek=WORD(Tm.GetDayOfWeek()); 00249 LocSysTm.wDay=WORD(Tm.GetDay()); 00250 LocSysTm.wHour=WORD(Tm.GetHour()); 00251 LocSysTm.wMinute=WORD(Tm.GetMin()); 00252 LocSysTm.wSecond=WORD(Tm.GetSec()); 00253 LocSysTm.wMilliseconds=WORD(Tm.GetMSec()); 00254 // convert system-time 00255 SYSTEMTIME UniSysTm=LocSysTm; 00256 Fail; // BCB5.0 doesn't find TzSpecificLocalTimeToSystemTime 00257 //TzSpecificLocalTimeToSystemTime(&TzInf, &LocSysTm, &UniSysTm); 00258 // return system-time 00259 return TTm(UniSysTm.wYear, UniSysTm.wMonth, UniSysTm.wDay, UniSysTm.wDayOfWeek, 00260 UniSysTm.wHour, UniSysTm.wMinute, UniSysTm.wSecond, UniSysTm.wMilliseconds); 00261 } 00262 00263 uint64 TSysTm::GetProcessMSecs(){ 00264 FILETIME CreationTime, ExitTime, KernelTime, UserTime; 00265 IAssert(GetProcessTimes(GetCurrentProcess(), 00266 &CreationTime, &ExitTime, &KernelTime, &UserTime)); 00267 TUInt64 KernelMSecs(uint(KernelTime.dwHighDateTime), uint(KernelTime.dwLowDateTime)); 00268 TUInt64 UserMSecs(uint(UserTime.dwHighDateTime), uint(UserTime.dwLowDateTime)); 00269 uint64 ProcessMSecs=KernelMSecs+UserMSecs; 00270 return ProcessMSecs; 00271 } 00272 00273 uint64 TSysTm::GetThreadMSecs(){ 00274 FILETIME CreationTime, ExitTime, KernelTime, UserTime; 00275 IAssert(GetProcessTimes(GetCurrentProcess(), 00276 &CreationTime, &ExitTime, &KernelTime, &UserTime)); 00277 TUInt64 KernelMSecs(uint(KernelTime.dwHighDateTime), uint(KernelTime.dwLowDateTime)); 00278 TUInt64 UserMSecs(uint(UserTime.dwHighDateTime), uint(UserTime.dwLowDateTime)); 00279 uint64 ThreadMSecs=KernelMSecs+UserMSecs; 00280 return ThreadMSecs; 00281 } 00282 00283 uint64 TSysTm::GetPerfTimerFq(){ 00284 uint MsFq; uint LsFq; 00285 LARGE_INTEGER LargeInt; 00286 if (QueryPerformanceFrequency(&LargeInt)){ 00287 MsFq=LargeInt.u.HighPart; 00288 LsFq=LargeInt.u.LowPart; 00289 } else { 00290 MsFq=0; 00291 LsFq=1; 00292 } 00293 TUInt64 UInt64(MsFq, LsFq); 00294 return UInt64.Val; 00295 } 00296 00297 uint64 TSysTm::GetPerfTimerTicks(){ 00298 uint MsVal; uint LsVal; 00299 LARGE_INTEGER LargeInt; 00300 if (QueryPerformanceCounter(&LargeInt)){ 00301 MsVal=LargeInt.u.HighPart; 00302 LsVal=LargeInt.u.LowPart; 00303 } else { 00304 MsVal=0; 00305 LsVal=int(time(NULL)); 00306 } 00307 TUInt64 UInt64(MsVal, LsVal); 00308 return UInt64.Val; 00309 } 00310 00312 // System-Strings 00313 TStr TSysStr::GetCmLn(){ 00314 return TStr((char*)GetCommandLine()); 00315 } 00316 00317 TStr TSysStr::GetMsgStr(const DWORD& MsgCd){ 00318 // retrieve message string 00319 LPVOID lpMsgBuf; 00320 FormatMessage( 00321 FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM, 00322 NULL, 00323 MsgCd, 00324 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language 00325 (LPTSTR) &lpMsgBuf, 00326 0, 00327 NULL); 00328 // save string 00329 TStr MsgStr((char*)lpMsgBuf); 00330 // free the buffer. 00331 LocalFree(lpMsgBuf); 00332 return MsgStr; 00333 } 00334 00335 char* TSysStr::GetLastMsgCStr(){ 00336 TStr MsgStr=GetLastMsgStr(); 00337 static char* MsgCStr=NULL; 00338 if (MsgCStr==NULL){MsgCStr=new char[1000];} 00339 strcpy(MsgCStr, MsgStr.CStr()); 00340 return MsgCStr; 00341 } 00342 00344 // Registry-Key 00345 PRegKey TRegKey::GetKey(const PRegKey& BaseKey, const TStr& SubKeyNm){ 00346 HKEY hKey; 00347 DWORD RetCd=RegOpenKeyEx( 00348 BaseKey->GetHandle(), SubKeyNm.CStr(), 0, KEY_ALL_ACCESS, &hKey); 00349 bool Ok=RetCd==ERROR_SUCCESS; 00350 return new TRegKey(Ok, hKey); 00351 } 00352 00353 TStr TRegKey::GetVal(const PRegKey& Key, const TStr& SubKeyNm, const TStr& ValNm){ 00354 PRegKey RegKey=TRegKey::GetKey(Key, SubKeyNm); 00355 if (RegKey->IsOk()){ 00356 TStrKdV ValNmStrKdV; RegKey->GetValV(ValNmStrKdV); 00357 int ValN; 00358 if (ValNmStrKdV.IsIn(TStrKd(ValNm), ValN)){ 00359 return ValNmStrKdV[ValN].Dat; 00360 } else { 00361 return ""; 00362 } 00363 } else { 00364 return ""; 00365 } 00366 } 00367 00368 void TRegKey::GetKeyNmV(TStrV& KeyNmV) const { 00369 KeyNmV.Clr(); 00370 if (!Ok){return;} 00371 // get subkey count 00372 DWORD SubKeys; // number of subkeys 00373 DWORD MxSubKeyNmLen; // longest subkey size 00374 DWORD RetCd=RegQueryInfoKey( 00375 hKey, // key handle 00376 NULL, // buffer for class name 00377 NULL, // length of class string 00378 NULL, // reserved 00379 &SubKeys, // number of subkeys 00380 &MxSubKeyNmLen, // longest subkey size 00381 NULL, // longest class string 00382 NULL, // number of values for this key 00383 NULL, // longest value name 00384 NULL, // longest value data 00385 NULL, // security descriptor 00386 NULL); // last write time 00387 if (RetCd!=ERROR_SUCCESS){return;} 00388 00389 // retrieve subkey-names 00390 if (SubKeys>0){ 00391 KeyNmV.Gen(SubKeys, 0); 00392 char* SubKeyNmCStr=new char[MxSubKeyNmLen+1]; 00393 DWORD SubKeyN=0; 00394 forever{ 00395 DWORD SubKeyNmCStrLen=MxSubKeyNmLen+1; 00396 DWORD RetCd=RegEnumKeyEx( 00397 hKey, // handle of key to enumerate 00398 SubKeyN, // index of subkey to enumerate 00399 SubKeyNmCStr, // address of buffer for subkey name 00400 &SubKeyNmCStrLen, // address for size of subkey buffer 00401 NULL, // reserved 00402 NULL, // address of buffer for class string 00403 NULL, // address for size of class buffer 00404 NULL); // address for time key last written to 00405 if (RetCd==ERROR_SUCCESS){ 00406 TStr KeyNm(SubKeyNmCStr); 00407 KeyNmV.Add(KeyNm); 00408 } else { 00409 break; 00410 } 00411 SubKeyN++; 00412 } 00413 delete[] SubKeyNmCStr; 00414 } 00415 } 00416 00417 void TRegKey::GetValV(TStrKdV& ValNmStrKdV) const { 00418 ValNmStrKdV.Clr(); 00419 if (!Ok){return;} 00420 // get subkey count 00421 DWORD Vals; // number of values 00422 DWORD MxValNmLen; // longest value name 00423 DWORD MxValStrLen; // longest value data 00424 DWORD RetCd=RegQueryInfoKey( 00425 hKey, // key handle 00426 NULL, // buffer for class name 00427 NULL, // length of class string 00428 NULL, // reserved 00429 NULL, // number of subkeys 00430 NULL, // longest subkey size 00431 NULL, // longest class string 00432 &Vals, // number of values for this key 00433 &MxValNmLen, // longest value name 00434 &MxValStrLen, // longest value data 00435 NULL, // security descriptor 00436 NULL); // last write time 00437 if (RetCd!=ERROR_SUCCESS){return;} 00438 00439 // retrieve subkey-names 00440 if (Vals>0){ 00441 ValNmStrKdV.Gen(Vals, 0); 00442 char* ValNmCStr=new char[MxValNmLen+1]; 00443 char* ValCStr=new char[MxValStrLen+1]; 00444 DWORD ValN=0; 00445 forever{ 00446 DWORD ValNmCStrLen=MxValNmLen+1; 00447 DWORD ValCStrLen=MxValStrLen+1; 00448 DWORD ValType; 00449 DWORD RetCd=RegEnumValue( 00450 hKey, // handle of key to query 00451 ValN, // index of value to query 00452 ValNmCStr, // address of buffer for value string 00453 &ValNmCStrLen, // address for size of value buffer 00454 NULL, // reserved 00455 &ValType, // address of buffer for type code 00456 (unsigned char*) ValCStr, // address of buffer for value data 00457 &ValCStrLen); // address for size of data buffer 00458 if (RetCd==ERROR_SUCCESS){ 00459 if (ValType==REG_SZ){ 00460 TStr ValNm(ValNmCStr); 00461 TStr ValStr(ValCStr); 00462 ValNmStrKdV.Add(TStrKd(ValNm, ValStr)); 00463 } 00464 } else { 00465 break; 00466 } 00467 ValN++; 00468 } 00469 delete[] ValNmCStr; 00470 delete[] ValCStr; 00471 } 00472 } 00473 00475 // Program StdIn and StdOut redirection using pipes 00476 void TStdIOPipe::CreateProc(const TStr& Cmd) { 00477 PROCESS_INFORMATION piProcInfo; 00478 STARTUPINFO siStartInfo; 00479 ZeroMemory( &piProcInfo, sizeof(PROCESS_INFORMATION)); 00480 ZeroMemory( &siStartInfo, sizeof(STARTUPINFO)); 00481 siStartInfo.cb = sizeof(STARTUPINFO); 00482 siStartInfo.hStdInput = ChildStdinRd; 00483 siStartInfo.hStdOutput = ChildStdoutWr; 00484 siStartInfo.dwFlags |= STARTF_USESTDHANDLES; 00485 // Create the child process. 00486 const BOOL FuncRetn = CreateProcess(NULL, 00487 (LPSTR) Cmd.CStr(), // command line 00488 NULL, // process security attributes 00489 NULL, // primary thread security attributes 00490 TRUE, // handles are inherited 00491 0, // creation flags 00492 NULL, // use parent's environment 00493 NULL, // use parent's current directory 00494 &siStartInfo, // STARTUPINFO pointer 00495 &piProcInfo); // receives PROCESS_INFORMATION 00496 EAssertR(FuncRetn!=0, TStr::Fmt("Can not execute '%s'", Cmd.CStr()).CStr()); 00497 CloseHandle(piProcInfo.hProcess); 00498 CloseHandle(piProcInfo.hThread); 00499 } 00500 00501 TStdIOPipe::TStdIOPipe(const TStr& CmdToExe) : ChildStdinRd(NULL), ChildStdinWrDup(NULL), 00502 ChildStdoutWr(NULL), ChildStdoutRdDup(NULL) { 00503 HANDLE ChildStdinWr, ChildStdoutRd; 00504 SECURITY_ATTRIBUTES saAttr; 00505 // Set the bInheritHandle flag so pipe handles are inherited. 00506 saAttr.nLength = sizeof(SECURITY_ATTRIBUTES); 00507 saAttr.bInheritHandle = TRUE; 00508 saAttr.lpSecurityDescriptor = NULL; 00509 // Create a pipe for the child process's STDOUT. 00510 EAssert(CreatePipe(&ChildStdoutRd, &ChildStdoutWr, &saAttr, 0)); 00511 // Create noninheritable read handle and close the inheritable read handle. 00512 EAssert(DuplicateHandle(GetCurrentProcess(), ChildStdoutRd, 00513 GetCurrentProcess(), &ChildStdoutRdDup, 0, FALSE, DUPLICATE_SAME_ACCESS)); 00514 CloseHandle(ChildStdoutRd); 00515 // Create a pipe for the child process's STDIN. 00516 EAssert(CreatePipe(&ChildStdinRd, &ChildStdinWr, &saAttr, 0)); 00517 // Duplicate the write handle to the pipe so it is not inherited. 00518 EAssert(DuplicateHandle(GetCurrentProcess(), ChildStdinWr, 00519 GetCurrentProcess(), &ChildStdinWrDup, 0, FALSE, DUPLICATE_SAME_ACCESS)); 00520 CloseHandle(ChildStdinWr); 00521 // Now create the child process. 00522 CreateProc(CmdToExe); 00523 } 00524 00525 TStdIOPipe::~TStdIOPipe() { 00526 if (ChildStdinRd != NULL) CloseHandle(ChildStdinRd); 00527 if (ChildStdinWrDup != NULL) CloseHandle(ChildStdinWrDup); 00528 if (ChildStdoutWr != NULL) CloseHandle(ChildStdoutWr); 00529 if (ChildStdoutRdDup != NULL) CloseHandle(ChildStdoutRdDup); 00530 } 00531 00532 int TStdIOPipe::Write(const char* Bf, const int& BfLen) { 00533 DWORD Written; 00534 EAssert(WriteFile(ChildStdinWrDup, Bf, BfLen, &Written, NULL)); 00535 return int(Written); 00536 } 00537 00538 int TStdIOPipe::Read(char *Bf, const int& BfMxLen) { 00539 DWORD Read; 00540 EAssert(ReadFile(ChildStdoutRdDup, Bf, BfMxLen, &Read, NULL)); 00541 return int(Read); 00542 } 00543 00544 #elif defined(GLib_UNIX) 00545 00547 // Compatibility functions 00548 int GetModuleFileName(void *hModule, char *Bf, int MxBfL) { 00549 int retlen = (int) readlink("/proc/self/exe", Bf, MxBfL); 00550 if (retlen == -1) { 00551 if (MxBfL > 0) Bf[0] = '\0'; 00552 return 0; 00553 } 00554 if (retlen == MxBfL) --retlen; 00555 Bf[retlen] = '\0'; 00556 return retlen; 00557 } 00558 00559 int GetCurrentDirectory(const int MxBfL, char *Bf) { 00560 getcwd(Bf, MxBfL); 00561 return (int) strlen(Bf); 00562 } 00563 00564 int CreateDirectory(const char *FNm, void *useless) { 00565 return mkdir(FNm, 0777)==0; 00566 } 00567 00568 int RemoveDirectory(const char *FNm) { 00569 return unlink(FNm)==0; 00570 } 00571 00572 #define TICKS_PER_SECOND 10000000 00573 #define EPOCH_DIFFERENCE 11644473600LL 00574 00576 uint64 Epoch2Ft(time_t Epoch){ 00577 uint64 Ft; 00578 Ft = Epoch + EPOCH_DIFFERENCE; // Adds seconds between epochs 00579 Ft *= TICKS_PER_SECOND; // Converts from seconds to 100ns intervals 00580 return Ft; 00581 } 00582 00584 time_t Ft2Epoch(uint64 Ft){ 00585 uint64 Epoch; 00586 Epoch = Ft / TICKS_PER_SECOND; // Converts from 100ns intervals to seconds 00587 Epoch -= EPOCH_DIFFERENCE; // Subtracts seconds between epochs 00588 return (time_t) Epoch; 00589 } 00590 00592 // System-Time 00593 TTm TSysTm::GetCurUniTm(){ 00594 time_t t; 00595 struct tm tms; 00596 struct timeval tv; 00597 00598 time(&t); 00599 int ErrCd = gettimeofday(&tv, NULL); 00600 if (ErrCd == 0) { 00601 Assert((ErrCd==0)&&(t!=-1)); 00602 } 00603 gmtime_r(&t, &tms); 00604 00605 return TTm(1900+tms.tm_year, tms.tm_mon, tms.tm_mday, tms.tm_wday, 00606 tms.tm_hour, tms.tm_min, tms.tm_sec, tv.tv_usec/1000); 00607 } 00608 00609 TTm TSysTm::GetCurLocTm(){ 00610 time_t t; 00611 struct tm tms; 00612 struct timeval tv; 00613 00614 time(&t); 00615 int ErrCd = gettimeofday(&tv, NULL); 00616 if (ErrCd == 0) { 00617 Assert((ErrCd==0)&&(t!=-1)); 00618 } 00619 localtime_r(&t, &tms); 00620 00621 return TTm(1900+tms.tm_year, tms.tm_mon, tms.tm_mday, tms.tm_wday, 00622 tms.tm_hour, tms.tm_min, tms.tm_sec, tv.tv_usec/1000); 00623 } 00624 00625 uint64 TSysTm::GetCurUniMSecs(){ 00626 return TTm::GetMSecsFromTm(GetCurLocTm()); 00627 } 00628 00629 uint64 TSysTm::GetCurLocMSecs(){ 00630 return TTm::GetMSecsFromTm(GetCurUniTm()); 00631 } 00632 00633 uint64 TSysTm::GetMSecsFromTm(const TTm& Tm){ 00634 time_t t; 00635 struct tm tms; 00636 tms.tm_year = Tm.GetYear() - 1900; 00637 tms.tm_mon = Tm.GetMonth(); 00638 tms.tm_mday = Tm.GetDay(); 00639 tms.tm_hour = Tm.GetHour(); 00640 tms.tm_min = Tm.GetMin(); 00641 tms.tm_sec = Tm.GetSec(); 00642 00643 t = timegm(&tms); 00644 return Epoch2Ft(t)/10000 + (uint64)Tm.GetMSec(); 00645 } 00646 00647 TTm TSysTm::GetTmFromMSecs(const uint64& TmNum){ 00648 const int MSec = int(TmNum % 1000); 00649 time_t Sec = Ft2Epoch(TmNum*10000); 00650 00651 struct tm tms; 00652 gmtime_r(&Sec, &tms); 00653 00654 return TTm(1900+tms.tm_year, tms.tm_mon, tms.tm_mday, tms.tm_wday, 00655 tms.tm_hour, tms.tm_min, tms.tm_sec, MSec); 00656 } 00657 00658 TTm TSysTm::GetLocTmFromUniTm(const TTm& Tm) { 00659 struct tm tms, tmr; 00660 00661 tms.tm_year = Tm.GetYear() - 1900; 00662 tms.tm_mon = Tm.GetMonth(); 00663 tms.tm_mday = Tm.GetDay(); 00664 tms.tm_hour = Tm.GetHour(); 00665 tms.tm_min = Tm.GetMin(); 00666 tms.tm_sec = Tm.GetSec(); 00667 int MSec = Tm.GetMSec(); 00668 00669 time_t Sec = timegm(&tms); 00670 localtime_r(&Sec, &tmr); 00671 00672 return TTm(1900+tmr.tm_year, tmr.tm_mon, tmr.tm_mday, tmr.tm_wday, 00673 tmr.tm_hour, tmr.tm_min, tmr.tm_sec, MSec); 00674 } 00675 00676 TTm TSysTm::GetUniTmFromLocTm(const TTm& Tm) { 00677 struct tm tms, tmr; 00678 00679 tms.tm_year = Tm.GetYear() - 1900; 00680 tms.tm_mon = Tm.GetMonth(); 00681 tms.tm_mday = Tm.GetDay(); 00682 tms.tm_hour = Tm.GetHour(); 00683 tms.tm_min = Tm.GetMin(); 00684 tms.tm_sec = Tm.GetSec(); 00685 tms.tm_isdst = -1; // ask the system to figure out DST 00686 int MSec = Tm.GetMSec(); 00687 00688 time_t Sec = mktime(&tms); 00689 gmtime_r(&Sec, &tmr); 00690 00691 return TTm(1900+tmr.tm_year, tmr.tm_mon, tmr.tm_mday, tmr.tm_wday, 00692 tmr.tm_hour, tmr.tm_min, tmr.tm_sec, MSec); 00693 } 00694 00695 uint TSysTm::GetMSecsFromOsStart(){ 00696 #if defined(_POSIX_MONOTONIC_CLOCK) && (_POSIX_MONOTONIC_CLOCK != -1) 00697 struct timespec ts; 00698 int ErrCd=clock_gettime(CLOCK_MONOTONIC, &ts); 00699 if (ErrCd == 0) { 00700 Assert(ErrCd==0); 00701 } 00702 return (ts.tv_sec*1000) + (ts.tv_nsec/1000000); 00703 #else 00704 FILE *f; 00705 uint sec, csec; 00706 f = fopen("/proc/uptime", "r"); 00707 if (!f) return 0xffffffff; // !bn: assert 00708 fscanf(f, "%u.%u", &sec, &csec); 00709 fclose(f); 00710 return (uint) (sec * 1000) + (csec * 10); 00711 #endif 00712 } 00713 00714 uint64 TSysTm::GetProcessMSecs() { 00715 #if defined(_POSIX_CPUTIME) && (_POSIX_CPUTIME != -1) 00716 struct timespec ts; 00717 int ErrCd=clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &ts); 00718 if (ErrCd == 0) { 00719 Assert(ErrCd==0); 00720 } 00721 return (ts.tv_sec*1000) + (ts.tv_nsec / 1000000); 00722 #else 00723 //#warning "CLOCK_PROCESS_CPUTIME not available; using getrusage" 00724 struct rusage ru; 00725 int ErrCd = getrusage(RUSAGE_SELF, &ru); 00726 if (ErrCd == 0) { 00727 Assert(ErrCd == 0); 00728 } 00729 return ((ru.ru_utime.tv_usec + ru.ru_stime.tv_usec) / 1000) + 00730 ((ru.ru_utime.tv_sec + ru.ru_stime.tv_sec) * 1000); 00731 #endif 00732 } 00733 00734 uint64 TSysTm::GetThreadMSecs() { 00735 #if defined(_POSIX_THREAD_CPUTIME) && (_POSIX_THREAD_CPUTIME != -1) 00736 struct timespec ts; 00737 int ErrCd=clock_gettime(CLOCK_THREAD_CPUTIME_ID, &ts); 00738 if (ErrCd == 0) { 00739 Assert(ErrCd==0); 00740 } 00741 return (ts.tv_sec*1000) + (ts.tv_nsec / 1000000); 00742 #else 00743 //#warning "CLOCK_THREAD_CPUTIME not available; using GetProcessMSecs()" 00744 return GetProcessMSecs(); 00745 #endif 00746 } 00747 00748 uint64 TSysTm::GetPerfTimerFq(){ 00749 #if defined(_POSIX_MONOTONIC_CLOCK) && (_POSIX_MONOTONIC_CLOCK != -1) 00750 return 1000000000; 00751 #else 00752 return 1000000; 00753 #endif 00754 } 00755 00756 uint64 TSysTm::GetPerfTimerTicks(){ 00757 #if defined(_POSIX_MONOTONIC_CLOCK) && (_POSIX_MONOTONIC_CLOCK != -1) 00758 struct timespec ts; 00759 int ErrCd=clock_gettime(CLOCK_MONOTONIC, &ts); 00760 //Assert(ErrCd==0); //J: vcasih se prevede in ne dela 00761 if (ErrCd != 0) { 00762 return (uint64)ts.tv_sec*1000000000ll + (uint64)ts.tv_nsec; } 00763 else { 00764 struct timeval tv; 00765 gettimeofday(&tv, NULL); 00766 return (uint64)tv.tv_usec + ((uint64)tv.tv_sec)*1000000; 00767 } 00768 #else 00769 //#warning "CLOCK_MONOTONIC not available; using gettimeofday()" 00770 struct timeval tv; 00771 gettimeofday(&tv, NULL); 00772 return (uint64)tv.tv_usec + ((uint64)tv.tv_sec)*1000000; 00773 #endif 00774 } 00775 00777 // System-Processes 00778 int TSysProc::Sleep(const uint& MSecs) { 00779 int ret; 00780 struct timespec tsp, trem; 00781 tsp.tv_sec = MSecs / 1000; 00782 tsp.tv_nsec = (MSecs % 1000) * 1000000; 00783 00784 while (true) { 00785 ret = nanosleep(&tsp, &trem); 00786 if ((ret != -1) || (errno != EINTR)) { 00787 break; 00788 } 00789 tsp = trem; 00790 } 00791 00792 return ret; 00793 } 00794 00795 TStr TSysProc::GetExeFNm() { 00796 char Bf[1024]; 00797 GetModuleFileName(NULL, Bf, 1023); 00798 return TStr(Bf); 00799 } 00800 00801 void TSysProc::SetLowPriority() { 00802 nice(19); 00803 } 00804 00805 bool TSysProc::ExeProc(const TStr& ExeFNm, TStr& ParamStr) { 00806 TStrV SArgV; 00807 ParamStr.SplitOnWs(SArgV); 00808 00809 int pid = fork(); 00810 if (pid == -1) return false; 00811 if (pid > 0) return true; 00812 00813 char **argv; 00814 argv = new char*[SArgV.Len()+2]; 00815 argv[0] = strdup(ExeFNm.CStr()); 00816 for (int i=0;i<SArgV.Len();i++) argv[i+1] = strdup(SArgV[i].CStr()); 00817 argv[SArgV.Len()+1] = NULL; 00818 00819 execvp(argv[0], argv); 00820 00821 //BF: moved role of TSysMsg to TLoop and TSockSys in net.h, hence removed the following inline 00822 //TSysMsg::Quit(); 00823 kill(getpid(), SIGINT); 00824 return false; 00825 } 00826 00828 // System-Messages 00829 //void TSysMsg::Loop() { 00830 // //bn!!! zdej mamo pa problem. kaksne msgje? samo za sockete? 00831 // //!!! tle je treba klicat AsyncSys iz net::sock.cpp 00832 // //#define TOTALNAZMEDA 00833 // //#ifdef TOTALNAZMEDA 00834 // //class TAsyncSys; 00835 // //extern TAsyncSys AsyncSys; 00836 // //AsyncSys::AsyncLoop(); 00837 // //#endif 00838 // FailR("Not intended for use under Linux!"); 00839 //} 00840 // 00841 //void TSysMsg::Quit() { 00842 // kill(getpid(), SIGINT); 00843 //} 00844 00846 // Program StdIn and StdOut redirection using pipes 00847 // J: not yet ported to Linux 00848 TStdIOPipe::TStdIOPipe(const TStr& CmdToExe) { 00849 FailR("Not intended for use under Linux!"); 00850 } 00851 00852 TStdIOPipe::~TStdIOPipe() { 00853 FailR("Not intended for use under Linux!"); 00854 } 00855 00856 int TStdIOPipe::Write(const char* Bf, const int& BfLen) { 00857 FailR("Not intended for use under Linux!"); 00858 return -1; 00859 } 00860 00861 int TStdIOPipe::Read(char *Bf, const int& BfMxLen) { 00862 FailR("Not intended for use under Linux!"); 00863 return -1; 00864 } 00865 00866 #endif 00867