SNAP Library 2.0, Developer Reference
2013-05-13 16:33:57
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 Assert((ErrCd==0)&&(t!=-1)); 00601 gmtime_r(&t, &tms); 00602 00603 return TTm(1900+tms.tm_year, tms.tm_mon, tms.tm_mday, tms.tm_wday, 00604 tms.tm_hour, tms.tm_min, tms.tm_sec, tv.tv_usec/1000); 00605 } 00606 00607 TTm TSysTm::GetCurLocTm(){ 00608 time_t t; 00609 struct tm tms; 00610 struct timeval tv; 00611 00612 time(&t); 00613 int ErrCd = gettimeofday(&tv, NULL); 00614 Assert((ErrCd==0)&&(t!=-1)); 00615 localtime_r(&t, &tms); 00616 00617 return TTm(1900+tms.tm_year, tms.tm_mon, tms.tm_mday, tms.tm_wday, 00618 tms.tm_hour, tms.tm_min, tms.tm_sec, tv.tv_usec/1000); 00619 } 00620 00621 uint64 TSysTm::GetCurUniMSecs(){ 00622 return TTm::GetMSecsFromTm(GetCurLocTm()); 00623 } 00624 00625 uint64 TSysTm::GetCurLocMSecs(){ 00626 return TTm::GetMSecsFromTm(GetCurUniTm()); 00627 } 00628 00629 uint64 TSysTm::GetMSecsFromTm(const TTm& Tm){ 00630 time_t t; 00631 struct tm tms; 00632 tms.tm_year = Tm.GetYear() - 1900; 00633 tms.tm_mon = Tm.GetMonth(); 00634 tms.tm_mday = Tm.GetDay(); 00635 tms.tm_hour = Tm.GetHour(); 00636 tms.tm_min = Tm.GetMin(); 00637 tms.tm_sec = Tm.GetSec(); 00638 00639 t = timegm(&tms); 00640 return Epoch2Ft(t)/10000 + (uint64)Tm.GetMSec(); 00641 } 00642 00643 TTm TSysTm::GetTmFromMSecs(const uint64& TmNum){ 00644 const int MSec = int(TmNum % 1000); 00645 time_t Sec = Ft2Epoch(TmNum*10000); 00646 00647 struct tm tms; 00648 gmtime_r(&Sec, &tms); 00649 00650 return TTm(1900+tms.tm_year, tms.tm_mon, tms.tm_mday, tms.tm_wday, 00651 tms.tm_hour, tms.tm_min, tms.tm_sec, MSec); 00652 } 00653 00654 TTm TSysTm::GetLocTmFromUniTm(const TTm& Tm) { 00655 struct tm tms, tmr; 00656 00657 tms.tm_year = Tm.GetYear() - 1900; 00658 tms.tm_mon = Tm.GetMonth(); 00659 tms.tm_mday = Tm.GetDay(); 00660 tms.tm_hour = Tm.GetHour(); 00661 tms.tm_min = Tm.GetMin(); 00662 tms.tm_sec = Tm.GetSec(); 00663 int MSec = Tm.GetMSec(); 00664 00665 time_t Sec = timegm(&tms); 00666 localtime_r(&Sec, &tmr); 00667 00668 return TTm(1900+tmr.tm_year, tmr.tm_mon, tmr.tm_mday, tmr.tm_wday, 00669 tmr.tm_hour, tmr.tm_min, tmr.tm_sec, MSec); 00670 } 00671 00672 TTm TSysTm::GetUniTmFromLocTm(const TTm& Tm) { 00673 struct tm tms, tmr; 00674 00675 tms.tm_year = Tm.GetYear() - 1900; 00676 tms.tm_mon = Tm.GetMonth(); 00677 tms.tm_mday = Tm.GetDay(); 00678 tms.tm_hour = Tm.GetHour(); 00679 tms.tm_min = Tm.GetMin(); 00680 tms.tm_sec = Tm.GetSec(); 00681 tms.tm_isdst = -1; // ask the system to figure out DST 00682 int MSec = Tm.GetMSec(); 00683 00684 time_t Sec = mktime(&tms); 00685 gmtime_r(&Sec, &tmr); 00686 00687 return TTm(1900+tmr.tm_year, tmr.tm_mon, tmr.tm_mday, tmr.tm_wday, 00688 tmr.tm_hour, tmr.tm_min, tmr.tm_sec, MSec); 00689 } 00690 00691 uint TSysTm::GetMSecsFromOsStart(){ 00692 #if defined(_POSIX_MONOTONIC_CLOCK) && (_POSIX_MONOTONIC_CLOCK != -1) 00693 struct timespec ts; 00694 int ErrCd=clock_gettime(CLOCK_MONOTONIC, &ts); 00695 Assert(ErrCd==0); 00696 return (ts.tv_sec*1000) + (ts.tv_nsec/1000000); 00697 #else 00698 FILE *f; 00699 uint sec, csec; 00700 f = fopen("/proc/uptime", "r"); 00701 if (!f) return 0xffffffff; // !bn: assert 00702 fscanf(f, "%u.%u", &sec, &csec); 00703 fclose(f); 00704 return (uint) (sec * 1000) + (csec * 10); 00705 #endif 00706 } 00707 00708 uint64 TSysTm::GetProcessMSecs() { 00709 #if defined(_POSIX_CPUTIME) && (_POSIX_CPUTIME != -1) 00710 struct timespec ts; 00711 int ErrCd=clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &ts); 00712 Assert(ErrCd==0); 00713 return (ts.tv_sec*1000) + (ts.tv_nsec / 1000000); 00714 #else 00715 //#warning "CLOCK_PROCESS_CPUTIME not available; using getrusage" 00716 struct rusage ru; 00717 int ErrCd = getrusage(RUSAGE_SELF, &ru); 00718 Assert(ErrCd == 0); 00719 return ((ru.ru_utime.tv_usec + ru.ru_stime.tv_usec) / 1000) + 00720 ((ru.ru_utime.tv_sec + ru.ru_stime.tv_sec) * 1000); 00721 #endif 00722 } 00723 00724 uint64 TSysTm::GetThreadMSecs() { 00725 #if defined(_POSIX_THREAD_CPUTIME) && (_POSIX_THREAD_CPUTIME != -1) 00726 struct timespec ts; 00727 int ErrCd=clock_gettime(CLOCK_THREAD_CPUTIME_ID, &ts); 00728 Assert(ErrCd==0); 00729 return (ts.tv_sec*1000) + (ts.tv_nsec / 1000000); 00730 #else 00731 //#warning "CLOCK_THREAD_CPUTIME not available; using GetProcessMSecs()" 00732 return GetProcessMSecs(); 00733 #endif 00734 } 00735 00736 uint64 TSysTm::GetPerfTimerFq(){ 00737 #if defined(_POSIX_MONOTONIC_CLOCK) && (_POSIX_MONOTONIC_CLOCK != -1) 00738 return 1000000000; 00739 #else 00740 return 1000000; 00741 #endif 00742 } 00743 00744 uint64 TSysTm::GetPerfTimerTicks(){ 00745 #if defined(_POSIX_MONOTONIC_CLOCK) && (_POSIX_MONOTONIC_CLOCK != -1) 00746 struct timespec ts; 00747 int ErrCd=clock_gettime(CLOCK_MONOTONIC, &ts); 00748 //Assert(ErrCd==0); //J: vcasih se prevede in ne dela 00749 if (ErrCd != 0) { 00750 return (uint64)ts.tv_sec*1000000000ll + (uint64)ts.tv_nsec; } 00751 else { 00752 struct timeval tv; 00753 gettimeofday(&tv, NULL); 00754 return (uint64)tv.tv_usec + ((uint64)tv.tv_sec)*1000000; 00755 } 00756 #else 00757 //#warning "CLOCK_MONOTONIC not available; using gettimeofday()" 00758 struct timeval tv; 00759 gettimeofday(&tv, NULL); 00760 return (uint64)tv.tv_usec + ((uint64)tv.tv_sec)*1000000; 00761 #endif 00762 } 00763 00765 // System-Processes 00766 int TSysProc::Sleep(const uint& MSecs) { 00767 int ret; 00768 struct timespec tsp, trem; 00769 tsp.tv_sec = MSecs / 1000; 00770 tsp.tv_nsec = (MSecs % 1000) * 1000000; 00771 00772 while (true) { 00773 ret = nanosleep(&tsp, &trem); 00774 if ((ret != -1) || (errno != EINTR)) { 00775 break; 00776 } 00777 tsp = trem; 00778 } 00779 00780 return ret; 00781 } 00782 00783 TStr TSysProc::GetExeFNm() { 00784 char Bf[1024]; 00785 GetModuleFileName(NULL, Bf, 1023); 00786 return TStr(Bf); 00787 } 00788 00789 void TSysProc::SetLowPriority() { 00790 nice(19); 00791 } 00792 00793 bool TSysProc::ExeProc(const TStr& ExeFNm, TStr& ParamStr) { 00794 TStrV SArgV; 00795 ParamStr.SplitOnWs(SArgV); 00796 00797 int pid = fork(); 00798 if (pid == -1) return false; 00799 if (pid > 0) return true; 00800 00801 char **argv; 00802 argv = new char*[SArgV.Len()+2]; 00803 argv[0] = strdup(ExeFNm.CStr()); 00804 for (int i=0;i<SArgV.Len();i++) argv[i+1] = strdup(SArgV[i].CStr()); 00805 argv[SArgV.Len()+1] = NULL; 00806 00807 execvp(argv[0], argv); 00808 00809 //BF: moved role of TSysMsg to TLoop and TSockSys in net.h, hence removed the following inline 00810 //TSysMsg::Quit(); 00811 kill(getpid(), SIGINT); 00812 return false; 00813 } 00814 00816 // System-Messages 00817 //void TSysMsg::Loop() { 00818 // //bn!!! zdej mamo pa problem. kaksne msgje? samo za sockete? 00819 // //!!! tle je treba klicat AsyncSys iz net::sock.cpp 00820 // //#define TOTALNAZMEDA 00821 // //#ifdef TOTALNAZMEDA 00822 // //class TAsyncSys; 00823 // //extern TAsyncSys AsyncSys; 00824 // //AsyncSys::AsyncLoop(); 00825 // //#endif 00826 // FailR("Not intended for use under Linux!"); 00827 //} 00828 // 00829 //void TSysMsg::Quit() { 00830 // kill(getpid(), SIGINT); 00831 //} 00832 00834 // Program StdIn and StdOut redirection using pipes 00835 // J: not yet ported to Linux 00836 TStdIOPipe::TStdIOPipe(const TStr& CmdToExe) { 00837 FailR("Not intended for use under Linux!"); 00838 } 00839 00840 TStdIOPipe::~TStdIOPipe() { 00841 FailR("Not intended for use under Linux!"); 00842 } 00843 00844 int TStdIOPipe::Write(const char* Bf, const int& BfLen) { 00845 FailR("Not intended for use under Linux!"); 00846 return -1; 00847 } 00848 00849 int TStdIOPipe::Read(char *Bf, const int& BfMxLen) { 00850 FailR("Not intended for use under Linux!"); 00851 return -1; 00852 } 00853 00854 #endif 00855