SNAP Library, Developer Reference  2012-10-15 15:06:59
SNAP, a general purpose network analysis and graph mining library
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
os.cpp
Go to the documentation of this file.
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