SNAP Library 6.0, Developer Reference  2020-12-09 16:24:20
SNAP, a general purpose, high performance system for analysis and manipulation of large networks
os.cpp
Go to the documentation of this file.
1 #ifdef GLib_WIN
2 
4 // System-Processes
5 void TSysProc::Sleep(const uint& MSecs){
6  SleepEx(MSecs, false);
7 }
8 
9 TStr TSysProc::GetExeFNm(){
10  DWORD MxFNmLen=1024;
11  LPTSTR FNmCStr=new char[MxFNmLen];
12  DWORD FNmLen=GetModuleFileName(NULL, FNmCStr, MxFNmLen);
13  TStr FNm;
14  if (FNmLen!=0){
15  FNm=FNmCStr;}
16  delete[] FNmCStr;
17  return FNm;
18 }
19 
20 void TSysProc::SetLowPriority(){
21  SetPriorityClass(GetCurrentProcess(), IDLE_PRIORITY_CLASS);
22 }
23 
24 bool TSysProc::ExeProc(const TStr& ExeFNm, TStr& ParamStr){
25  STARTUPINFO si;
26  PROCESS_INFORMATION pi;
27  ZeroMemory(&si, sizeof(si));
28  si.cb=sizeof(si);
29  ZeroMemory(&pi, sizeof(pi));
30 
31  // Start the child process.
32  BOOL Ok=CreateProcess(
33  ExeFNm.CStr(), // module name
34  ParamStr.CStr(), // patameters
35  NULL, // Process handle not inheritable.
36  NULL, // Thread handle not inheritable.
37  FALSE, // Set handle inheritance to FALSE.
38  0, // No creation flags.
39  NULL, // Use parent's environment block.
40  NULL, // Use parent's starting directory.
41  &si, // Pointer to STARTUPINFO structure.
42  &pi); // Pointer to PROCESS_INFORMATION structure.
43  if (Ok){
44  // Wait until child process exits.
45  WaitForSingleObject( pi.hProcess, INFINITE );
46  // Close process and thread handles.
47  CloseHandle( pi.hProcess );
48  CloseHandle( pi.hThread );
49  return true;
50  } else {
51  return false;
52  }
53 }
54 
56 // Memory-Status
57 TStr TSysMemStat::GetLoadStr(){
58  static TStr MemUsageStr="Mem Load: ";
59  TChA ChA;
60  ChA+=MemUsageStr;
61  ChA+=TUInt64::GetStr(GetLoad());
62  ChA+="%";
63  return ChA;
64 }
65 
66 TStr TSysMemStat::GetUsageStr(){
67  static TStr MemUsageStr="Mem Usage: ";
68  uint64 GlobalUsage=GetTotalPageFile()-GetAvailPageFile();
69  TChA ChA;
70  ChA+=MemUsageStr;
71  ChA+=TUInt64::GetStr(GlobalUsage/1024);
72  ChA+="K / ";
73  ChA+=TUInt64::GetStr(GetTotalPageFile()/1024);
74  ChA+="K";
75  return ChA;
76 }
77 
78 TStr TSysMemStat::GetInfoStr(){
79  TChA ChA;
80  ChA+="Memory Load:";
81  ChA+=TUInt64::GetMegaStr(GetLoad()); ChA+="\r\n";
82  ChA+="Total Physical:";
83  ChA+=TUInt64::GetMegaStr(GetTotalPhys()); ChA+="\r\n";
84  ChA+="Available Physical:";
85  ChA+=TUInt64::GetMegaStr(GetAvailPhys()); ChA+="\r\n";
86  ChA+="Total Page File:";
87  ChA+=TUInt64::GetMegaStr(GetTotalPageFile()); ChA+="\r\n";
88  ChA+="Available Page File:";
89  ChA+=TUInt64::GetMegaStr(GetAvailPageFile()); ChA+="\r\n";
90  ChA+="Total Virtual:";
91  ChA+=TUInt64::GetMegaStr(GetTotalVirtual()); ChA+="\r\n";
92  ChA+="Available Virtual:";
93  ChA+=TUInt64::GetMegaStr(GetAvailVirtual()); ChA+="\r\n";
94  return ChA;
95 }
96 
97 TStr TSysMemStat::GetStr(){
98  TChA ChA;
99  ChA+=TUInt64::GetStr(GetLoad()); ChA+=' ';
100  ChA+=TUInt64::GetStr(GetTotalPhys()); ChA+=' ';
101  ChA+=TUInt64::GetStr(GetAvailPhys()); ChA+=' ';
102  ChA+=TUInt64::GetStr(GetTotalPageFile()); ChA+=' ';
103  ChA+=TUInt64::GetStr(GetAvailPageFile()); ChA+=' ';
104  ChA+=TUInt64::GetStr(GetTotalVirtual()); ChA+=' ';
105  ChA+=TUInt64::GetStr(GetAvailVirtual());
106  return ChA;
107 }
108 
110 // System-Console
111 TSysConsole::TSysConsole(){
112  Ok=(AllocConsole()!=0);
113  IAssert(Ok);
114  hStdOut=GetStdHandle(STD_OUTPUT_HANDLE);
115  IAssert(hStdOut!=INVALID_HANDLE_VALUE);
116 }
117 
118 TSysConsole::~TSysConsole(){
119  if (Ok){
120  IAssert(FreeConsole());}
121 }
122 
123 void TSysConsole::Put(const TStr& Str){
124  DWORD ChsWritten;
125  WriteConsole(hStdOut, Str.CStr(), Str.Len(), &ChsWritten, NULL);
126  IAssert(ChsWritten==DWORD(Str.Len()));
127 }
128 
130 // System-Console-Notifier
131 void TSysConsoleNotify::OnNotify(const TNotifyType& Type, const TStr& MsgStr){
132  if (Type==ntInfo){
133  SysConsole->PutLn(TStr::Fmt("%s", MsgStr.CStr()));
134  } else {
135  TStr TypeStr=TNotify::GetTypeStr(Type, false);
136  SysConsole->PutLn(TStr::Fmt("%s: %s", TypeStr.CStr(), MsgStr.CStr()));
137  }
138 }
139 
140 void TSysConsoleNotify::OnStatus(const TStr& MsgStr){
141  SysConsole->Put(MsgStr.CStr());
142  // print '\n' if message not overlayed
143  if ((!MsgStr.Empty())&&(MsgStr.LastCh()!='\r')){
144  SysConsole->PutLn(""); }
145 }
146 
148 // System-Messages
149 //void TSysMsg::Loop(){
150 // MSG Msg;
151 // while (GetMessage(&Msg, NULL, 0, 0 )){
152 // TranslateMessage(&Msg); DispatchMessage(&Msg);}
153 //}
154 //
155 //void TSysMsg::Quit(){PostQuitMessage(0);}
156 
158 // System-Time
159 TTm TSysTm::GetCurUniTm(){
160  SYSTEMTIME SysTm;
161  GetSystemTime(&SysTm);
162  return TTm(SysTm.wYear, SysTm.wMonth, SysTm.wDay, SysTm.wDayOfWeek,
163  SysTm.wHour, SysTm.wMinute, SysTm.wSecond, SysTm.wMilliseconds);
164 }
165 
166 TTm TSysTm::GetCurLocTm(){
167  SYSTEMTIME SysTm;
168  GetLocalTime(&SysTm);
169  return TTm(SysTm.wYear, SysTm.wMonth, SysTm.wDay, SysTm.wDayOfWeek,
170  SysTm.wHour, SysTm.wMinute, SysTm.wSecond, SysTm.wMilliseconds);
171 }
172 
173 uint64 TSysTm::GetCurUniMSecs(){
174  SYSTEMTIME SysTm; FILETIME FileTm;
175  GetSystemTime(&SysTm);
176  IAssert(SystemTimeToFileTime(&SysTm, &FileTm));
177  TUInt64 UInt64(uint(FileTm.dwHighDateTime), uint(FileTm.dwLowDateTime));
178  return UInt64.Val/uint64(10000);
179 }
180 
181 uint64 TSysTm::GetCurLocMSecs(){
182  SYSTEMTIME SysTm; FILETIME FileTm;
183  GetLocalTime(&SysTm);
184  IAssert(SystemTimeToFileTime(&SysTm, &FileTm));
185  TUInt64 UInt64(uint(FileTm.dwHighDateTime), uint(FileTm.dwLowDateTime));
186  return UInt64.Val/uint64(10000);
187 }
188 
189 uint64 TSysTm::GetMSecsFromTm(const TTm& Tm){
190  SYSTEMTIME SysTm; FILETIME FileTm;
191  SysTm.wYear=WORD(Tm.GetYear());
192  SysTm.wMonth=WORD(Tm.GetMonth());
193  SysTm.wDayOfWeek=WORD(Tm.GetDayOfWeek());
194  SysTm.wDay=WORD(Tm.GetDay());
195  SysTm.wHour=WORD(Tm.GetHour());
196  SysTm.wMinute=WORD(Tm.GetMin());
197  SysTm.wSecond=WORD(Tm.GetSec());
198  SysTm.wMilliseconds=WORD(Tm.GetMSec());
199  ESAssert(SystemTimeToFileTime(&SysTm, &FileTm));
200  TUInt64 UInt64(uint(FileTm.dwHighDateTime), uint(FileTm.dwLowDateTime));
201  return UInt64.Val/uint64(10000);
202 }
203 
204 TTm TSysTm::GetTmFromMSecs(const uint64& MSecs){
205  TUInt64 FileTmUnits(MSecs*uint64(10000));
206  SYSTEMTIME SysTm; FILETIME FileTm;
207  FileTm.dwHighDateTime=FileTmUnits.GetMsVal();
208  FileTm.dwLowDateTime=FileTmUnits.GetLsVal();
209  SAssert(FileTimeToSystemTime(&FileTm, &SysTm));
210  return TTm(SysTm.wYear, SysTm.wMonth, SysTm.wDay, SysTm.wDayOfWeek,
211  SysTm.wHour, SysTm.wMinute, SysTm.wSecond, SysTm.wMilliseconds);
212 }
213 
214 uint TSysTm::GetMSecsFromOsStart(){
215  return uint(GetTickCount());
216 }
217 
218 TTm TSysTm::GetLocTmFromUniTm(const TTm& Tm){
219  // get time-zone information
220  TIME_ZONE_INFORMATION TzInf;
221  GetTimeZoneInformation(&TzInf);
222  // get system time
223  SYSTEMTIME UniSysTm;
224  UniSysTm.wYear=WORD(Tm.GetYear());
225  UniSysTm.wMonth=WORD(Tm.GetMonth());
226  UniSysTm.wDayOfWeek=WORD(Tm.GetDayOfWeek());
227  UniSysTm.wDay=WORD(Tm.GetDay());
228  UniSysTm.wHour=WORD(Tm.GetHour());
229  UniSysTm.wMinute=WORD(Tm.GetMin());
230  UniSysTm.wSecond=WORD(Tm.GetSec());
231  UniSysTm.wMilliseconds=WORD(Tm.GetMSec());
232  // convert system-time
233  SYSTEMTIME LocSysTm;
234  SystemTimeToTzSpecificLocalTime(&TzInf, &UniSysTm, &LocSysTm);
235  // return local-time
236  return TTm(LocSysTm.wYear, LocSysTm.wMonth, LocSysTm.wDay, LocSysTm.wDayOfWeek,
237  LocSysTm.wHour, LocSysTm.wMinute, LocSysTm.wSecond, LocSysTm.wMilliseconds);
238 }
239 
240 TTm TSysTm::GetUniTmFromLocTm(const TTm& Tm){
241  // get time-zone information
242  TIME_ZONE_INFORMATION TzInf;
243  GetTimeZoneInformation(&TzInf);
244  // get system time
245  SYSTEMTIME LocSysTm;
246  LocSysTm.wYear=WORD(Tm.GetYear());
247  LocSysTm.wMonth=WORD(Tm.GetMonth());
248  LocSysTm.wDayOfWeek=WORD(Tm.GetDayOfWeek());
249  LocSysTm.wDay=WORD(Tm.GetDay());
250  LocSysTm.wHour=WORD(Tm.GetHour());
251  LocSysTm.wMinute=WORD(Tm.GetMin());
252  LocSysTm.wSecond=WORD(Tm.GetSec());
253  LocSysTm.wMilliseconds=WORD(Tm.GetMSec());
254  // convert system-time
255  SYSTEMTIME UniSysTm=LocSysTm;
256  Fail; // BCB5.0 doesn't find TzSpecificLocalTimeToSystemTime
257  //TzSpecificLocalTimeToSystemTime(&TzInf, &LocSysTm, &UniSysTm);
258  // return system-time
259  return TTm(UniSysTm.wYear, UniSysTm.wMonth, UniSysTm.wDay, UniSysTm.wDayOfWeek,
260  UniSysTm.wHour, UniSysTm.wMinute, UniSysTm.wSecond, UniSysTm.wMilliseconds);
261 }
262 
263 uint64 TSysTm::GetProcessMSecs(){
264  FILETIME CreationTime, ExitTime, KernelTime, UserTime;
265  IAssert(GetProcessTimes(GetCurrentProcess(),
266  &CreationTime, &ExitTime, &KernelTime, &UserTime));
267  TUInt64 KernelMSecs(uint(KernelTime.dwHighDateTime), uint(KernelTime.dwLowDateTime));
268  TUInt64 UserMSecs(uint(UserTime.dwHighDateTime), uint(UserTime.dwLowDateTime));
269  uint64 ProcessMSecs=KernelMSecs+UserMSecs;
270  return ProcessMSecs;
271 }
272 
273 uint64 TSysTm::GetThreadMSecs(){
274  FILETIME CreationTime, ExitTime, KernelTime, UserTime;
275  IAssert(GetProcessTimes(GetCurrentProcess(),
276  &CreationTime, &ExitTime, &KernelTime, &UserTime));
277  TUInt64 KernelMSecs(uint(KernelTime.dwHighDateTime), uint(KernelTime.dwLowDateTime));
278  TUInt64 UserMSecs(uint(UserTime.dwHighDateTime), uint(UserTime.dwLowDateTime));
279  uint64 ThreadMSecs=KernelMSecs+UserMSecs;
280  return ThreadMSecs;
281 }
282 
283 uint64 TSysTm::GetPerfTimerFq(){
284  uint MsFq; uint LsFq;
285  LARGE_INTEGER LargeInt;
286  if (QueryPerformanceFrequency(&LargeInt)){
287  MsFq=LargeInt.u.HighPart;
288  LsFq=LargeInt.u.LowPart;
289  } else {
290  MsFq=0;
291  LsFq=1;
292  }
293  TUInt64 UInt64(MsFq, LsFq);
294  return UInt64.Val;
295 }
296 
297 uint64 TSysTm::GetPerfTimerTicks(){
298  uint MsVal; uint LsVal;
299  LARGE_INTEGER LargeInt;
300  if (QueryPerformanceCounter(&LargeInt)){
301  MsVal=LargeInt.u.HighPart;
302  LsVal=LargeInt.u.LowPart;
303  } else {
304  MsVal=0;
305  LsVal=int(time(NULL));
306  }
307  TUInt64 UInt64(MsVal, LsVal);
308  return UInt64.Val;
309 }
310 
312 // System-Strings
313 TStr TSysStr::GetCmLn(){
314  return TStr((char*)GetCommandLine());
315 }
316 
317 TStr TSysStr::GetMsgStr(const DWORD& MsgCd){
318  // retrieve message string
319  LPVOID lpMsgBuf;
320  FormatMessage(
321  FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM,
322  NULL,
323  MsgCd,
324  MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
325  (LPTSTR) &lpMsgBuf,
326  0,
327  NULL);
328  // save string
329  TStr MsgStr((char*)lpMsgBuf);
330  // free the buffer.
331  LocalFree(lpMsgBuf);
332  return MsgStr;
333 }
334 
335 char* TSysStr::GetLastMsgCStr(){
336  TStr MsgStr=GetLastMsgStr();
337  static char* MsgCStr=NULL;
338  if (MsgCStr==NULL){MsgCStr=new char[1000];}
339  strcpy(MsgCStr, MsgStr.CStr());
340  return MsgCStr;
341 }
342 
344 // Registry-Key
345 PRegKey TRegKey::GetKey(const PRegKey& BaseKey, const TStr& SubKeyNm){
346  HKEY hKey;
347  DWORD RetCd=RegOpenKeyEx(
348  BaseKey->GetHandle(), SubKeyNm.CStr(), 0, KEY_ALL_ACCESS, &hKey);
349  bool Ok=RetCd==ERROR_SUCCESS;
350  return new TRegKey(Ok, hKey);
351 }
352 
353 TStr TRegKey::GetVal(const PRegKey& Key, const TStr& SubKeyNm, const TStr& ValNm){
354  PRegKey RegKey=TRegKey::GetKey(Key, SubKeyNm);
355  if (RegKey->IsOk()){
356  TStrKdV ValNmStrKdV; RegKey->GetValV(ValNmStrKdV);
357  int ValN;
358  if (ValNmStrKdV.IsIn(TStrKd(ValNm), ValN)){
359  return ValNmStrKdV[ValN].Dat;
360  } else {
361  return "";
362  }
363  } else {
364  return "";
365  }
366 }
367 
368 void TRegKey::GetKeyNmV(TStrV& KeyNmV) const {
369  KeyNmV.Clr();
370  if (!Ok){return;}
371  // get subkey count
372  DWORD SubKeys; // number of subkeys
373  DWORD MxSubKeyNmLen; // longest subkey size
374  DWORD RetCd=RegQueryInfoKey(
375  hKey, // key handle
376  NULL, // buffer for class name
377  NULL, // length of class string
378  NULL, // reserved
379  &SubKeys, // number of subkeys
380  &MxSubKeyNmLen, // longest subkey size
381  NULL, // longest class string
382  NULL, // number of values for this key
383  NULL, // longest value name
384  NULL, // longest value data
385  NULL, // security descriptor
386  NULL); // last write time
387  if (RetCd!=ERROR_SUCCESS){return;}
388 
389  // retrieve subkey-names
390  if (SubKeys>0){
391  KeyNmV.Gen(SubKeys, 0);
392  char* SubKeyNmCStr=new char[MxSubKeyNmLen+1];
393  DWORD SubKeyN=0;
394  forever{
395  DWORD SubKeyNmCStrLen=MxSubKeyNmLen+1;
396  DWORD RetCd=RegEnumKeyEx(
397  hKey, // handle of key to enumerate
398  SubKeyN, // index of subkey to enumerate
399  SubKeyNmCStr, // address of buffer for subkey name
400  &SubKeyNmCStrLen, // address for size of subkey buffer
401  NULL, // reserved
402  NULL, // address of buffer for class string
403  NULL, // address for size of class buffer
404  NULL); // address for time key last written to
405  if (RetCd==ERROR_SUCCESS){
406  TStr KeyNm(SubKeyNmCStr);
407  KeyNmV.Add(KeyNm);
408  } else {
409  break;
410  }
411  SubKeyN++;
412  }
413  delete[] SubKeyNmCStr;
414  }
415 }
416 
417 void TRegKey::GetValV(TStrKdV& ValNmStrKdV) const {
418  ValNmStrKdV.Clr();
419  if (!Ok){return;}
420  // get subkey count
421  DWORD Vals; // number of values
422  DWORD MxValNmLen; // longest value name
423  DWORD MxValStrLen; // longest value data
424  DWORD RetCd=RegQueryInfoKey(
425  hKey, // key handle
426  NULL, // buffer for class name
427  NULL, // length of class string
428  NULL, // reserved
429  NULL, // number of subkeys
430  NULL, // longest subkey size
431  NULL, // longest class string
432  &Vals, // number of values for this key
433  &MxValNmLen, // longest value name
434  &MxValStrLen, // longest value data
435  NULL, // security descriptor
436  NULL); // last write time
437  if (RetCd!=ERROR_SUCCESS){return;}
438 
439  // retrieve subkey-names
440  if (Vals>0){
441  ValNmStrKdV.Gen(Vals, 0);
442  char* ValNmCStr=new char[MxValNmLen+1];
443  char* ValCStr=new char[MxValStrLen+1];
444  DWORD ValN=0;
445  forever{
446  DWORD ValNmCStrLen=MxValNmLen+1;
447  DWORD ValCStrLen=MxValStrLen+1;
448  DWORD ValType;
449  DWORD RetCd=RegEnumValue(
450  hKey, // handle of key to query
451  ValN, // index of value to query
452  ValNmCStr, // address of buffer for value string
453  &ValNmCStrLen, // address for size of value buffer
454  NULL, // reserved
455  &ValType, // address of buffer for type code
456  (unsigned char*) ValCStr, // address of buffer for value data
457  &ValCStrLen); // address for size of data buffer
458  if (RetCd==ERROR_SUCCESS){
459  if (ValType==REG_SZ){
460  TStr ValNm(ValNmCStr);
461  TStr ValStr(ValCStr);
462  ValNmStrKdV.Add(TStrKd(ValNm, ValStr));
463  }
464  } else {
465  break;
466  }
467  ValN++;
468  }
469  delete[] ValNmCStr;
470  delete[] ValCStr;
471  }
472 }
473 
475 // Program StdIn and StdOut redirection using pipes
476 void TStdIOPipe::CreateProc(const TStr& Cmd) {
477  PROCESS_INFORMATION piProcInfo;
478  STARTUPINFO siStartInfo;
479  ZeroMemory( &piProcInfo, sizeof(PROCESS_INFORMATION));
480  ZeroMemory( &siStartInfo, sizeof(STARTUPINFO));
481  siStartInfo.cb = sizeof(STARTUPINFO);
482  siStartInfo.hStdInput = ChildStdinRd;
483  siStartInfo.hStdOutput = ChildStdoutWr;
484  siStartInfo.dwFlags |= STARTF_USESTDHANDLES;
485  // Create the child process.
486  const BOOL FuncRetn = CreateProcess(NULL,
487  (LPSTR) Cmd.CStr(), // command line
488  NULL, // process security attributes
489  NULL, // primary thread security attributes
490  TRUE, // handles are inherited
491  0, // creation flags
492  NULL, // use parent's environment
493  NULL, // use parent's current directory
494  &siStartInfo, // STARTUPINFO pointer
495  &piProcInfo); // receives PROCESS_INFORMATION
496  EAssertR(FuncRetn!=0, TStr::Fmt("Can not execute '%s'", Cmd.CStr()).CStr());
497  CloseHandle(piProcInfo.hProcess);
498  CloseHandle(piProcInfo.hThread);
499 }
500 
501 TStdIOPipe::TStdIOPipe(const TStr& CmdToExe) : ChildStdinRd(NULL), ChildStdinWrDup(NULL),
502  ChildStdoutWr(NULL), ChildStdoutRdDup(NULL) {
503  HANDLE ChildStdinWr, ChildStdoutRd;
504  SECURITY_ATTRIBUTES saAttr;
505  // Set the bInheritHandle flag so pipe handles are inherited.
506  saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
507  saAttr.bInheritHandle = TRUE;
508  saAttr.lpSecurityDescriptor = NULL;
509  // Create a pipe for the child process's STDOUT.
510  EAssert(CreatePipe(&ChildStdoutRd, &ChildStdoutWr, &saAttr, 0));
511  // Create noninheritable read handle and close the inheritable read handle.
512  EAssert(DuplicateHandle(GetCurrentProcess(), ChildStdoutRd,
513  GetCurrentProcess(), &ChildStdoutRdDup, 0, FALSE, DUPLICATE_SAME_ACCESS));
514  CloseHandle(ChildStdoutRd);
515  // Create a pipe for the child process's STDIN.
516  EAssert(CreatePipe(&ChildStdinRd, &ChildStdinWr, &saAttr, 0));
517  // Duplicate the write handle to the pipe so it is not inherited.
518  EAssert(DuplicateHandle(GetCurrentProcess(), ChildStdinWr,
519  GetCurrentProcess(), &ChildStdinWrDup, 0, FALSE, DUPLICATE_SAME_ACCESS));
520  CloseHandle(ChildStdinWr);
521  // Now create the child process.
522  CreateProc(CmdToExe);
523 }
524 
525 TStdIOPipe::~TStdIOPipe() {
526  if (ChildStdinRd != NULL) CloseHandle(ChildStdinRd);
527  if (ChildStdinWrDup != NULL) CloseHandle(ChildStdinWrDup);
528  if (ChildStdoutWr != NULL) CloseHandle(ChildStdoutWr);
529  if (ChildStdoutRdDup != NULL) CloseHandle(ChildStdoutRdDup);
530 }
531 
532 int TStdIOPipe::Write(const char* Bf, const int& BfLen) {
533  DWORD Written;
534  EAssert(WriteFile(ChildStdinWrDup, Bf, BfLen, &Written, NULL));
535  return int(Written);
536 }
537 
538 int TStdIOPipe::Read(char *Bf, const int& BfMxLen) {
539  DWORD Read;
540  EAssert(ReadFile(ChildStdoutRdDup, Bf, BfMxLen, &Read, NULL));
541  return int(Read);
542 }
543 
544 #elif defined(GLib_UNIX)
545 
547 // Compatibility functions
548 int GetModuleFileName(void *hModule, char *Bf, int MxBfL) {
549  int retlen = (int) readlink("/proc/self/exe", Bf, MxBfL);
550  if (retlen == -1) {
551  if (MxBfL > 0) Bf[0] = '\0';
552  return 0;
553  }
554  if (retlen == MxBfL) --retlen;
555  Bf[retlen] = '\0';
556  return retlen;
557 }
558 
559 int GetCurrentDirectory(const int MxBfL, char *Bf) {
560  getcwd(Bf, MxBfL);
561  return (int) strlen(Bf);
562 }
563 
564 int CreateDirectory(const char *FNm, void *useless) {
565  return mkdir(FNm, 0777)==0;
566 }
567 
568 int RemoveDirectory(const char *FNm) {
569  return unlink(FNm)==0;
570 }
571 
572 #define TICKS_PER_SECOND 10000000
573 #define EPOCH_DIFFERENCE 11644473600LL
574 
576 uint64 Epoch2Ft(time_t Epoch){
577  uint64 Ft;
578  Ft = Epoch + EPOCH_DIFFERENCE; // Adds seconds between epochs
579  Ft *= TICKS_PER_SECOND; // Converts from seconds to 100ns intervals
580  return Ft;
581 }
582 
584 time_t Ft2Epoch(uint64 Ft){
585  uint64 Epoch;
586  Epoch = Ft / TICKS_PER_SECOND; // Converts from 100ns intervals to seconds
587  Epoch -= EPOCH_DIFFERENCE; // Subtracts seconds between epochs
588  return (time_t) Epoch;
589 }
590 
592 // System-Time
593 TTm TSysTm::GetCurUniTm(){
594  time_t t;
595  struct tm tms;
596  struct timeval tv;
597 
598  time(&t);
599  int ErrCd = gettimeofday(&tv, NULL);
600  if (ErrCd != 0) {
601  Assert((ErrCd==0)&&(t!=-1));
602  }
603  gmtime_r(&t, &tms);
604 
605  return TTm(1900+tms.tm_year, tms.tm_mon, tms.tm_mday, tms.tm_wday,
606  tms.tm_hour, tms.tm_min, tms.tm_sec, tv.tv_usec/1000);
607 }
608 
609 TTm TSysTm::GetCurLocTm(){
610  time_t t;
611  struct tm tms;
612  struct timeval tv;
613 
614  time(&t);
615  int ErrCd = gettimeofday(&tv, NULL);
616  if (ErrCd != 0) {
617  Assert((ErrCd==0)&&(t!=-1));
618  }
619  localtime_r(&t, &tms);
620 
621  return TTm(1900+tms.tm_year, tms.tm_mon, tms.tm_mday, tms.tm_wday,
622  tms.tm_hour, tms.tm_min, tms.tm_sec, tv.tv_usec/1000);
623 }
624 
625 uint64 TSysTm::GetCurUniMSecs(){
626  return TTm::GetMSecsFromTm(GetCurLocTm());
627 }
628 
629 uint64 TSysTm::GetCurLocMSecs(){
630  return TTm::GetMSecsFromTm(GetCurUniTm());
631 }
632 
633 uint64 TSysTm::GetMSecsFromTm(const TTm& Tm){
634  time_t t;
635  struct tm tms;
636  tms.tm_year = Tm.GetYear() - 1900;
637  tms.tm_mon = Tm.GetMonth();
638  tms.tm_mday = Tm.GetDay();
639  tms.tm_hour = Tm.GetHour();
640  tms.tm_min = Tm.GetMin();
641  tms.tm_sec = Tm.GetSec();
642 
643  t = timegm(&tms);
644  return Epoch2Ft(t)/10000 + (uint64)Tm.GetMSec();
645 }
646 
647 TTm TSysTm::GetTmFromMSecs(const uint64& TmNum){
648  const int MSec = int(TmNum % 1000);
649  time_t Sec = Ft2Epoch(TmNum*10000);
650 
651  struct tm tms;
652  gmtime_r(&Sec, &tms);
653 
654  return TTm(1900+tms.tm_year, tms.tm_mon, tms.tm_mday, tms.tm_wday,
655  tms.tm_hour, tms.tm_min, tms.tm_sec, MSec);
656 }
657 
658 TTm TSysTm::GetLocTmFromUniTm(const TTm& Tm) {
659  struct tm tms, tmr;
660 
661  tms.tm_year = Tm.GetYear() - 1900;
662  tms.tm_mon = Tm.GetMonth();
663  tms.tm_mday = Tm.GetDay();
664  tms.tm_hour = Tm.GetHour();
665  tms.tm_min = Tm.GetMin();
666  tms.tm_sec = Tm.GetSec();
667  int MSec = Tm.GetMSec();
668 
669  time_t Sec = timegm(&tms);
670  localtime_r(&Sec, &tmr);
671 
672  return TTm(1900+tmr.tm_year, tmr.tm_mon, tmr.tm_mday, tmr.tm_wday,
673  tmr.tm_hour, tmr.tm_min, tmr.tm_sec, MSec);
674 }
675 
676 TTm TSysTm::GetUniTmFromLocTm(const TTm& Tm) {
677  struct tm tms, tmr;
678 
679  tms.tm_year = Tm.GetYear() - 1900;
680  tms.tm_mon = Tm.GetMonth();
681  tms.tm_mday = Tm.GetDay();
682  tms.tm_hour = Tm.GetHour();
683  tms.tm_min = Tm.GetMin();
684  tms.tm_sec = Tm.GetSec();
685  tms.tm_isdst = -1; // ask the system to figure out DST
686  int MSec = Tm.GetMSec();
687 
688  time_t Sec = mktime(&tms);
689  gmtime_r(&Sec, &tmr);
690 
691  return TTm(1900+tmr.tm_year, tmr.tm_mon, tmr.tm_mday, tmr.tm_wday,
692  tmr.tm_hour, tmr.tm_min, tmr.tm_sec, MSec);
693 }
694 
695 uint TSysTm::GetMSecsFromOsStart(){
696 #if defined(_POSIX_MONOTONIC_CLOCK) && (_POSIX_MONOTONIC_CLOCK != -1)
697  struct timespec ts;
698  int ErrCd=clock_gettime(CLOCK_MONOTONIC, &ts);
699  if (ErrCd != 0) {
700  Assert(ErrCd==0);
701  }
702  return (ts.tv_sec*1000) + (ts.tv_nsec/1000000);
703 #else
704  FILE *f;
705  uint sec, csec;
706  f = fopen("/proc/uptime", "r");
707  if (!f) return 0xffffffff; // !bn: assert
708  fscanf(f, "%u.%u", &sec, &csec);
709  fclose(f);
710  return (uint) (sec * 1000) + (csec * 10);
711 #endif
712 }
713 
714 uint64 TSysTm::GetProcessMSecs() {
715 #if defined(_POSIX_CPUTIME) && (_POSIX_CPUTIME != -1)
716  struct timespec ts;
717  int ErrCd=clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &ts);
718  if (ErrCd != 0) {
719  Assert(ErrCd==0);
720  }
721  return (ts.tv_sec*1000) + (ts.tv_nsec / 1000000);
722 #else
723  //#warning "CLOCK_PROCESS_CPUTIME not available; using getrusage"
724  struct rusage ru;
725  int ErrCd = getrusage(RUSAGE_SELF, &ru);
726  if (ErrCd != 0) {
727  Assert(ErrCd == 0);
728  }
729  return ((ru.ru_utime.tv_usec + ru.ru_stime.tv_usec) / 1000) +
730  ((ru.ru_utime.tv_sec + ru.ru_stime.tv_sec) * 1000);
731 #endif
732 }
733 
734 uint64 TSysTm::GetThreadMSecs() {
735 #if defined(_POSIX_THREAD_CPUTIME) && (_POSIX_THREAD_CPUTIME != -1)
736  struct timespec ts;
737  int ErrCd=clock_gettime(CLOCK_THREAD_CPUTIME_ID, &ts);
738  if (ErrCd != 0) {
739  Assert(ErrCd==0);
740  }
741  return (ts.tv_sec*1000) + (ts.tv_nsec / 1000000);
742 #else
743  //#warning "CLOCK_THREAD_CPUTIME not available; using GetProcessMSecs()"
744  return GetProcessMSecs();
745 #endif
746 }
747 
748 uint64 TSysTm::GetPerfTimerFq(){
749 #if defined(_POSIX_MONOTONIC_CLOCK) && (_POSIX_MONOTONIC_CLOCK != -1)
750  return 1000000000;
751 #else
752  return 1000000;
753 #endif
754 }
755 
756 uint64 TSysTm::GetPerfTimerTicks(){
757 #if defined(_POSIX_MONOTONIC_CLOCK) && (_POSIX_MONOTONIC_CLOCK != -1)
758  struct timespec ts;
759  int ErrCd=clock_gettime(CLOCK_MONOTONIC, &ts);
760  //Assert(ErrCd==0); //J: vcasih se prevede in ne dela
761  if (ErrCd != 0) {
762  return (uint64)ts.tv_sec*1000000000ll + (uint64)ts.tv_nsec; }
763  else {
764  struct timeval tv;
765  gettimeofday(&tv, NULL);
766  return (uint64)tv.tv_usec + ((uint64)tv.tv_sec)*1000000;
767  }
768 #else
769  //#warning "CLOCK_MONOTONIC not available; using gettimeofday()"
770  struct timeval tv;
771  gettimeofday(&tv, NULL);
772  return (uint64)tv.tv_usec + ((uint64)tv.tv_sec)*1000000;
773 #endif
774 }
775 
777 // System-Processes
778 int TSysProc::Sleep(const uint& MSecs) {
779  int ret;
780  struct timespec tsp, trem;
781  tsp.tv_sec = MSecs / 1000;
782  tsp.tv_nsec = (MSecs % 1000) * 1000000;
783 
784  while (true) {
785  ret = nanosleep(&tsp, &trem);
786  if ((ret != -1) || (errno != EINTR)) {
787  break;
788  }
789  tsp = trem;
790  }
791 
792  return ret;
793 }
794 
795 TStr TSysProc::GetExeFNm() {
796  char Bf[1024];
797  GetModuleFileName(NULL, Bf, 1023);
798  return TStr(Bf);
799 }
800 
801 void TSysProc::SetLowPriority() {
802  nice(19);
803 }
804 
805 bool TSysProc::ExeProc(const TStr& ExeFNm, TStr& ParamStr) {
806  TStrV SArgV;
807  ParamStr.SplitOnWs(SArgV);
808 
809  int pid = fork();
810  if (pid == -1) return false;
811  if (pid > 0) return true;
812 
813  char **argv;
814  argv = new char*[SArgV.Len()+2];
815  argv[0] = strdup(ExeFNm.CStr());
816  for (int i=0;i<SArgV.Len();i++) argv[i+1] = strdup(SArgV[i].CStr());
817  argv[SArgV.Len()+1] = NULL;
818 
819  execvp(argv[0], argv);
820 
821  //BF: moved role of TSysMsg to TLoop and TSockSys in net.h, hence removed the following inline
822  //TSysMsg::Quit();
823  kill(getpid(), SIGINT);
824  return false;
825 }
826 
828 // System-Messages
829 //void TSysMsg::Loop() {
830 // //bn!!! zdej mamo pa problem. kaksne msgje? samo za sockete?
831 // //!!! tle je treba klicat AsyncSys iz net::sock.cpp
832 // //#define TOTALNAZMEDA
833 // //#ifdef TOTALNAZMEDA
834 // //class TAsyncSys;
835 // //extern TAsyncSys AsyncSys;
836 // //AsyncSys::AsyncLoop();
837 // //#endif
838 // FailR("Not intended for use under Linux!");
839 //}
840 //
841 //void TSysMsg::Quit() {
842 // kill(getpid(), SIGINT);
843 //}
844 
846 // Program StdIn and StdOut redirection using pipes
847 // J: not yet ported to Linux
848 TStdIOPipe::TStdIOPipe(const TStr& CmdToExe) {
849  FailR("Not intended for use under Linux!");
850 }
851 
852 TStdIOPipe::~TStdIOPipe() {
853  FailR("Not intended for use under Linux!");
854 }
855 
856 int TStdIOPipe::Write(const char* Bf, const int& BfLen) {
857  FailR("Not intended for use under Linux!");
858  return -1;
859 }
860 
861 int TStdIOPipe::Read(char *Bf, const int& BfMxLen) {
862  FailR("Not intended for use under Linux!");
863  return -1;
864 }
865 
866 #endif
867 
Definition: ds.h:346
#define IAssert(Cond)
Definition: bd.h:262
int GetMin() const
Definition: tm.h:282
int GetMSec() const
Definition: tm.h:284
int Len() const
Definition: dt.h:490
static TStr GetTypeStr(const TNotifyType &Type, const bool &Brief=true)
Definition: ut.cpp:39
int GetMonth() const
Definition: tm.h:276
bool IsIn(const TVal &Val) const
Checks whether element Val is a member of the vector.
Definition: ds.h:828
#define forever
Definition: bd.h:6
unsigned int uint
Definition: bd.h:11
#define Fail
Definition: bd.h:238
TSizeTy Len() const
Returns the number of elements in the vector.
Definition: ds.h:575
int GetHour() const
Definition: tm.h:281
#define SAssert(Cond)
Definition: bd.h:271
static TStr GetMegaStr(const uint64 &Val)
Definition: dt.h:1372
int GetYear() const
Definition: tm.h:275
void Clr(const bool &DoDel=true, const TSizeTy &NoDelLim=-1)
Clears the contents of the vector.
Definition: ds.h:1022
#define ESAssert(Cond)
Definition: bd.h:292
unsigned long long uint64
Definition: bd.h:38
int GetDay() const
Definition: tm.h:278
#define Assert(Cond)
Definition: bd.h:251
char LastCh() const
Definition: dt.h:487
#define FailR(Reason)
Definition: bd.h:240
Definition: tm.h:213
Definition: dt.h:201
#define EAssert(Cond)
Definition: bd.h:280
TStr GetStr() const
Definition: dt.h:1363
int GetSec() const
Definition: tm.h:283
Definition: dt.h:412
bool Empty() const
Definition: dt.h:491
enum TNotifyType_ TNotifyType
static TStr Fmt(const char *FmtStr,...)
Definition: dt.cpp:1599
Definition: ut.h:28
#define EAssertR(Cond, MsgStr)
Definition: bd.h:283
int GetDayOfWeek() const
Definition: tm.h:279
void Gen(const TSizeTy &_Vals)
Constructs a vector (an array) of _Vals elements.
Definition: ds.h:523
void SplitOnWs(TStrV &StrV) const
Definition: dt.cpp:972
char * CStr()
Definition: dt.h:479
TSizeTy Add()
Adds a new element at the end of the vector, after its current last element.
Definition: ds.h:602
static uint64 GetMSecsFromTm(const TTm &Tm)
Definition: tm.cpp:1072
Definition: dt.h:1318
TKeyDat< TStr, TStr > TStrKd
Definition: ds.h:405