SNAP Library 2.1, Developer Reference  2013-09-25 10:47:25
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 // 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