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