SNAP Library , Developer Reference  2013-01-07 14:03:36
SNAP, a general purpose, high performance system for analysis and manipulation of large networks
 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