MRPT  1.9.9
os.cpp
Go to the documentation of this file.
1 /* +------------------------------------------------------------------------+
2  | Mobile Robot Programming Toolkit (MRPT) |
3  | https://www.mrpt.org/ |
4  | |
5  | Copyright (c) 2005-2020, Individual contributors, see AUTHORS file |
6  | See: https://www.mrpt.org/Authors - All rights reserved. |
7  | Released under BSD License. See: https://www.mrpt.org/License |
8  +------------------------------------------------------------------------+ */
9 
10 #include "system-precomp.h" // Precompiled headers
11 
12 #include <mrpt/core/exceptions.h>
13 #include <mrpt/core/format.h>
14 #include <mrpt/system/filesystem.h>
15 #include <mrpt/system/os.h>
16 
17 #ifndef HAVE_TIMEGM
18 #endif // HAVE_TIMEGM
19 
20 #include <algorithm>
21 #include <cctype>
22 #include <cfloat>
23 #include <cstdio>
24 #include <cstring>
25 #include <ctime>
26 #include <iostream>
27 
28 #ifdef _WIN32
29 #include <windows.h>
30 
31 #include <conio.h>
32 #include <direct.h>
33 #include <io.h>
34 #include <sys/utime.h>
35 #include <tlhelp32.h>
36 #else
37 #include <poll.h>
38 #include <pthread.h>
39 #include <sys/select.h>
40 #include <sys/time.h>
41 #include <termios.h>
42 #include <unistd.h>
43 #include <utime.h>
44 #include <cerrno>
45 #include <ctime>
46 // #include <signal.h>
47 #endif
48 
49 #include <sys/stat.h>
50 #include <sys/types.h>
51 
52 #ifdef MRPT_OS_LINUX
53 #define _access access
54 #define _rmdir rmdir
55 #define _stat stat
56 #endif
57 
58 #include <sstream>
59 
60 using namespace mrpt;
61 using namespace mrpt::system;
62 using namespace std;
63 
64 #ifndef _WIN32
65 /** By ninjalj in
66  * http://stackoverflow.com/questions/3962263/checking-if-a-key-was-pressed
67  */
68 void my_aux_sighandler(int) {}
69 int myKbhit()
70 {
71  struct termios oldtio
72  {
73  }, curtio{};
74  // struct sigaction sa;
75 
76  /* Save stdin terminal attributes */
77  tcgetattr(0, &oldtio);
78 
79  // memset(&sa, 0, sizeof(struct sigaction));
80 
81  /* Set non-canonical no-echo for stdin */
82  tcgetattr(0, &curtio);
83  curtio.c_lflag &= ~(ICANON | ECHO);
84  tcsetattr(0, TCSANOW, &curtio);
85 
86  struct pollfd pfds[1];
87 
88  /* See if there is data available */
89  pfds[0].fd = 0;
90  pfds[0].events = POLLIN;
91  const int ret = poll(pfds, 1, 0);
92 
93  /* restore terminal attributes */
94  tcsetattr(0, TCSANOW, &oldtio);
95 
96  return (ret > 0);
97 }
98 
99 #endif
100 
101 /*---------------------------------------------------------------
102  timegm
103  ---------------------------------------------------------------*/
104 #ifdef HAVE_TIMEGM
105 time_t mrpt::system::os::timegm(struct tm* tm) { return ::timegm(tm); }
106 #else
107 // Version for MSVC>=2005, which lacks "timegm"
108 #ifdef HAVE_MKGMTIME
109 time_t mrpt::system::os::timegm(struct tm* tm) { return ::_mkgmtime(tm); }
110 #else
111 // generic version, slower but probably not used in any modern compiler!
112 time_t mrpt::system::os::timegm(struct tm* tm)
113 {
114  static std::mutex cs;
115  std::lock_guard<std::mutex> lock(cs);
116 
117  time_t ret;
118  char tz[256];
119 
120  /* save current timezone and set UTC */
121  char* org_tz = getenv("TZ");
122  if (org_tz) os::strcpy(tz, sizeof(tz), org_tz);
123 
124  putenv("TZ=UTC"); /* use Coordinated Universal Time (i.e. zero offset) */
125  tzset();
126 
127  ret = mktime(tm);
128  if (org_tz)
129  {
130  char buf[256];
131  mrpt::system::os::sprintf(buf, sizeof(buf), "TZ=%s", tz);
132  putenv(buf);
133  }
134  else
135  putenv("TZ=");
136  tzset();
137 
138  return ret;
139 }
140 
141 #endif
142 #endif // HAVE_TIMEGM
143 
144 /*---------------------------------------------------------------
145  mrpt::system::MRPT_getCompilationDate
146 ---------------------------------------------------------------*/
147 #include <mrpt/version.h>
148 #include <cerrno>
149 #include <climits>
150 #include <cstdlib>
151 #include <ctime>
152 #include <limits>
153 
155 {
156  time_t now;
157  char* endptr;
158  const char* source_date_epoch = MRPT_SOURCE_DATE_EPOCH;
159 
160  errno = 0;
161  unsigned long epoch = strtoul(source_date_epoch, &endptr, 10);
162  if (epoch == 0 ||
163  ((errno == ERANGE &&
164  (epoch == std::numeric_limits<unsigned long>::max() || epoch == 0)) ||
165  (errno != 0 && epoch == 0)))
166  {
167  // Last resort:
168  now = time(nullptr);
169  }
170  else
171  {
172  now = epoch;
173  }
174  struct tm* build_time = gmtime(&now);
175  const int year = build_time->tm_year + 1900;
176  const int month = build_time->tm_mon + 1;
177  const int day = build_time->tm_mday;
178 
179  return mrpt::format(
180  "%i-%02i-%02i %02i:%02i:%02i UTC", year, month, day,
181  build_time->tm_hour, build_time->tm_min, build_time->tm_sec);
182 }
183 
184 /*---------------------------------------------------------------
185  mrpt::system::MRPT_getVersion
186 ---------------------------------------------------------------*/
187 string mrpt::system::MRPT_getVersion() { return string(::MRPT_version_str); }
188 /*---------------------------------------------------------------
189  sprintf
190 ---------------------------------------------------------------*/
191 int os::sprintf(char* buf, size_t bufSize, const char* format, ...) noexcept
192 {
193  MRPT_UNUSED_PARAM(bufSize);
194 
195  int result;
196  va_list ap;
197  va_start(ap, format);
198 
199 #if defined(_MSC_VER) && (_MSC_VER >= 1400)
200  // Use a secure version in Visual Studio 2005:
201  result = ::vsprintf_s(buf, bufSize, format, ap);
202 #else
203  // Use standard version:
204  result = ::vsprintf(buf, format, ap);
205 #endif
206 
207  va_end(ap);
208  return result;
209 }
210 
211 /*---------------------------------------------------------------
212  vsprintf
213 ---------------------------------------------------------------*/
215  char* buf, size_t bufSize, const char* format, va_list args) noexcept
216 {
217  MRPT_UNUSED_PARAM(bufSize);
218 #if defined(_MSC_VER) && (_MSC_VER >= 1400)
219  // Use a secure version in Visual Studio 2005:
220  return ::vsprintf_s(buf, bufSize, format, args);
221 #else
222  // Use standard version:
223  return ::vsprintf(buf, format, args);
224 #endif
225 }
226 
227 /*---------------------------------------------------------------
228  vsnprintf
229 ---------------------------------------------------------------*/
231  char* buf, size_t bufSize, const char* format, va_list args) noexcept
232 {
233 #if defined(_MSC_VER)
234 #if (_MSC_VER >= 1400)
235  // Use a secure version in Visual Studio 2005:
236  return ::vsnprintf_s(buf, bufSize, _TRUNCATE, format, args);
237 #else
238  return ::vsprintf(buf, format, args);
239 #endif
240 #else
241  // Use standard version:
242  return ::vsnprintf(buf, bufSize, format, args);
243 #endif
244 }
245 
246 /*---------------------------------------------------------------
247  fopen
248 ---------------------------------------------------------------*/
249 FILE* os::fopen(const std::string& fileName, const char* mode) noexcept
250 {
251  return fopen(fileName.c_str(), mode);
252 }
253 
254 /*---------------------------------------------------------------
255  fopen
256 ---------------------------------------------------------------*/
257 FILE* os::fopen(const char* fileName, const char* mode) noexcept
258 {
259 #if defined(_MSC_VER) && (_MSC_VER >= 1400)
260  // Use a secure version in Visual Studio 2005:
261  FILE* f;
262  if (0 != ::fopen_s(&f, fileName, mode))
263  return NULL;
264  else
265  return f;
266 #else
267  // Use standard version:
268  return ::fopen(fileName, mode);
269 #endif
270 }
271 
272 /*---------------------------------------------------------------
273  fclose
274 ---------------------------------------------------------------*/
275 void os::fclose(FILE* f)
276 {
277  if (!f) THROW_EXCEPTION("Trying to close a nullptr 'FILE*' descriptor");
278  ::fclose(f);
279 }
280 
281 /*---------------------------------------------------------------
282  strcat
283 ---------------------------------------------------------------*/
284 char* os::strcat(char* dest, size_t destSize, const char* source) noexcept
285 {
286  MRPT_UNUSED_PARAM(destSize);
287 
288 #if defined(_MSC_VER) && (_MSC_VER >= 1400)
289  ::strcat_s(dest, destSize, source);
290 #else
291  ::strcat(dest, source);
292 #endif
293  return dest;
294 }
295 
296 /*---------------------------------------------------------------
297  strcpy
298 ---------------------------------------------------------------*/
299 char* os::strcpy(char* dest, size_t destSize, const char* source) noexcept
300 {
301  MRPT_UNUSED_PARAM(destSize);
302 
303 #if defined(_MSC_VER) && (_MSC_VER >= 1400)
304  ::strcpy_s(dest, destSize, source);
305 #else
306  ::strcpy(dest, source);
307 #endif
308  return dest;
309 }
310 
311 /*---------------------------------------------------------------
312  strcmp
313 ---------------------------------------------------------------*/
314 int os::_strcmp(const char* str1, const char* str2) noexcept
315 {
316  return ::strcmp(str1, str2);
317 }
318 
319 /*---------------------------------------------------------------
320  strcmpi
321 ---------------------------------------------------------------*/
322 int os::_strcmpi(const char* str1, const char* str2) noexcept
323 {
324 #ifdef _WIN32
325 #if defined(_MSC_VER) && (_MSC_VER >= 1400)
326  return ::_strcmpi(str1, str2);
327 #else
328  return ::strcmpi(str1, str2);
329 #endif
330 #else
331  return ::strcasecmp(str1, str2);
332 #endif
333 }
334 
335 /** An OS-independent version of strncmp.
336  * \return It will return 0 when both strings are equal, casi sensitive.
337  */
338 int os::_strncmp(const char* str1, const char* str2, size_t count) noexcept
339 {
340  return ::strncmp(str1, str2, count);
341 }
342 
343 /** An OS-independent version of strnicmp.
344  * \return It will return 0 when both strings are equal, casi insensitive.
345  */
346 int os::_strnicmp(const char* str1, const char* str2, size_t count) noexcept
347 {
348 #if defined(_MSC_VER)
349  return ::_strnicmp(str1, str2, count);
350 #else
351  return ::strncasecmp(str1, str2, count);
352 #endif
353 }
354 
355 /*---------------------------------------------------------------
356  memcpy
357 ---------------------------------------------------------------*/
359  void* dest, size_t destSize, const void* src, size_t copyCount) noexcept
360 {
361 #if defined(_MSC_VER) && (_MSC_VER >= 1400)
362  ::memcpy_s(dest, destSize, src, copyCount);
363 #else
364  MRPT_UNUSED_PARAM(destSize);
365  ::memcpy(dest, src, copyCount);
366 #endif
367 }
368 
369 /*---------------------------------------------------------------
370  getch
371 ---------------------------------------------------------------*/
372 int os::getch() noexcept
373 {
374 #ifdef _WIN32
375  return ::getch(); // cin.get();
376 #else
377  struct termios oldt
378  {
379  }, newt{};
380  int ch;
381  tcgetattr(STDIN_FILENO, &oldt);
382  newt = oldt;
383  newt.c_lflag &= ~(ICANON | ECHO);
384  tcsetattr(STDIN_FILENO, TCSANOW, &newt);
385  ch = getchar();
386  tcsetattr(STDIN_FILENO, TCSANOW, &oldt);
387  return ch;
388 #endif
389 }
390 
391 /*---------------------------------------------------------------
392  kbhit
393 ---------------------------------------------------------------*/
394 bool os::kbhit() noexcept
395 {
396 #ifdef _WIN32
397 #if defined(_MSC_VER) && (_MSC_VER >= 1400)
398  return ::_kbhit() != 0;
399 #else
400  return ::kbhit() != 0;
401 #endif
402 #else
403  return myKbhit();
404 #endif
405 }
406 
407 /*---------------------------------------------------------------
408  os::fprintf
409 ---------------------------------------------------------------*/
410 int os::fprintf(FILE* fil, const char* frm, ...) noexcept
411 {
412  int result;
413  va_list ap;
414  va_start(ap, frm);
415 
416 #if defined(_MSC_VER) && (_MSC_VER >= 1400)
417  // Use a secure version in Visual Studio 2005:
418  result = ::vfprintf_s(fil, frm, ap);
419 
420 #else
421  // Use standard version:
422  result = ::vfprintf(fil, frm, ap);
423 #endif
424 
425  va_end(ap);
426  return result;
427 }
428 
429 /*---------------------------------------------------------------
430  mrpt::system::pause
431 ---------------------------------------------------------------*/
432 void mrpt::system::pause(const std::string& msg) noexcept
433 {
434  std::cout << msg << std::endl;
435  os::getch();
436 }
437 
438 /*---------------------------------------------------------------
439  clearConsole
440 ---------------------------------------------------------------*/
442 {
443 #ifdef _WIN32
444  int ret = ::system("cls");
445 #else
446  int ret = ::system("clear");
447 #endif
448  if (ret)
449  cerr << "[mrpt::system::clearConsole] Error invoking 'clear screen' "
450  << endl;
451 }
452 
453 /*---------------------------------------------------------------
454  _strtoll
455  ---------------------------------------------------------------*/
456 int64_t mrpt::system::os::_strtoll(const char* nptr, char** endptr, int base)
457 {
458 #ifdef _WIN32
459  return (int64_t)::strtol(nptr, endptr, base);
460 #else
461  return (int64_t)::strtoll(nptr, endptr, base);
462 #endif
463 }
464 
465 /*---------------------------------------------------------------
466  _strtoull
467  ---------------------------------------------------------------*/
468 uint64_t mrpt::system::os::_strtoull(const char* nptr, char** endptr, int base)
469 {
470 #ifdef _WIN32
471  return (uint64_t)::strtoul(nptr, endptr, base);
472 #else
473  return (uint64_t)::strtoull(nptr, endptr, base);
474 #endif
475 }
476 
477 /** Changes the text color in the console for the text written from now on.
478  * The parameter "color" can be:
479  * - 0 : Normal text color
480  * - 1 : Blue text color
481  * - 2 : Green text color
482  * - 4 : Red text color
483  */
484 void mrpt::system::setConsoleColor(TConsoleColor color, bool changeStdErr)
485 {
486  static const int TS_NORMAL = 0;
487  static const int TS_BLUE = 1;
488  static const int TS_GREEN = 2;
489  static const int TS_RED = 4;
490 #ifdef _WIN32
491  static int normal_attributes = -1;
492  HANDLE hstdout =
493  GetStdHandle(changeStdErr ? STD_ERROR_HANDLE : STD_OUTPUT_HANDLE);
494  fflush(changeStdErr ? stderr : stdout);
495 
496  if (normal_attributes < 0)
497  {
498  CONSOLE_SCREEN_BUFFER_INFO info;
499  GetConsoleScreenBufferInfo(hstdout, &info);
500  normal_attributes = info.wAttributes;
501  }
502 
503  SetConsoleTextAttribute(
504  hstdout,
505  (WORD)(
506  color == TS_NORMAL ? normal_attributes
507  : ((color & TS_BLUE ? FOREGROUND_BLUE : 0) |
508  (color & TS_GREEN ? FOREGROUND_GREEN : 0) |
509  (color & TS_RED ? FOREGROUND_RED : 0) |
510  FOREGROUND_INTENSITY)));
511 #else
512  // *nix:
513  static TConsoleColor last_color = mrpt::system::CONCOL_NORMAL;
514  if (color == last_color) return;
515  last_color = color;
516 
517  static const uint8_t ansi_tab[] = {30, 34, 32, 36, 31, 35, 33, 37};
518  int code = 0;
519  fflush(changeStdErr ? stdout : stderr);
520  if (color != TS_NORMAL)
521  code = ansi_tab[color & (TS_BLUE | TS_GREEN | TS_RED)];
522  fprintf(changeStdErr ? stdout : stderr, "\x1b[%dm", code);
523 #endif
524 }
525 
526 const char* sLicenseTextF =
527  " Mobile Robot Programming Toolkit (MRPT) "
528  " \n"
529  " https://www.mrpt.org/ "
530  " "
531  " \n"
532  " "
533  " \n"
534  " Copyright (c) 2005-%Y, Individual contributors, see AUTHORS file "
535  "\n"
536  " See: https://www.mrpt.org/Authors - All rights reserved. "
537  " "
538  " \n"
539  " Released under BSD License. See details in https://www.mrpt.org/License "
540  " "
541  " \n";
542 
543 const std::string& mrpt::system::getMRPTLicense()
544 {
545  static bool sLicenseTextReady = false;
546  static std::string sLicenseText;
547 
548  if (!sLicenseTextReady)
549  {
550  // Automatically update the last year of the copyright to the
551  // compilation date:
552  time_t rawtime;
553  struct tm* timeinfo;
554  time(&rawtime);
555  timeinfo = localtime(&rawtime);
556 
557  char buf[1024];
558  ::strftime(buf, sizeof(buf), sLicenseTextF, timeinfo);
559  sLicenseText = std::string(buf);
560  sLicenseTextReady = true;
561  }
562  return sLicenseText;
563 }
564 
565 #ifdef _WIN32
566 std::string winerror2str(const char* errorPlaceName)
567 {
568  char str[700];
569  DWORD e = GetLastError();
570  FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, 0, e, 0, str, sizeof(str), NULL);
571  std::string s;
572  s = "[";
573  s += errorPlaceName;
574  s += "] Error: ";
575  s += str;
576  return s;
577 }
578 #endif
579 
580 /*---------------------------------------------------------------
581 launchProcess
582 ---------------------------------------------------------------*/
583 bool mrpt::system::launchProcess(const std::string& command)
584 {
585 #ifdef _WIN32
586  STARTUPINFOA SI;
587  PROCESS_INFORMATION PI;
588  memset(&SI, 0, sizeof(STARTUPINFOA));
589  SI.cb = sizeof(STARTUPINFOA);
590  if (CreateProcessA(
591  NULL, (LPSTR)command.c_str(), NULL, NULL, true, 0, NULL, NULL, &SI,
592  &PI))
593  {
594  // Wait:
595  WaitForSingleObject(PI.hProcess, INFINITE);
596  return true;
597  } // End of process executed OK
598  else
599  {
600  std::cerr << winerror2str("launchProcess");
601  return false;
602  }
603 
604 #else
605 
606  return 0 == ::system(command.c_str());
607 
608 #endif
609 
610 } // end launchProcess
611 
612 #include <mrpt/mrpt_paths_config.h>
614 {
615  static bool mrpt_shared_first_call = true;
616  static std::string found_mrpt_shared_dir;
617 
618  if (mrpt_shared_first_call)
619  {
620  mrpt_shared_first_call = false;
621 
622  for (int attempt = 0;; attempt++)
623  {
624  std::string dir;
625  switch (attempt)
626  {
627  case 0:
628  dir = string(MRPT_SOURCE_BASE_DIRECTORY) +
629  string("/share/mrpt/");
630  break;
631  case 1:
632  dir = string(MRPT_INSTALL_PREFIX_DIRECTORY) +
633  string("/share/mrpt/");
634  break;
635 #ifdef _WIN32
636  case 2:
637  {
638  char curExe[4096];
639  GetModuleFileNameA(nullptr, curExe, sizeof(curExe));
640 
642  std::string(curExe)) +
643  "/../share/mrpt/";
644  }
645  break;
646 #endif
647 
648  default:
649  found_mrpt_shared_dir = ".";
650  break;
651  };
652  if (!dir.empty() && mrpt::system::directoryExists(dir))
653  found_mrpt_shared_dir = dir;
654 
655  if (!found_mrpt_shared_dir.empty()) break;
656  }
657  }
658 
659  return found_mrpt_shared_dir;
660 } // end of find_mrpt_shared_dir
661 
663  const std::string& command, std::string* output /*=NULL*/,
664  const std::string& mode /*="r"*/)
665 {
666  using namespace std;
667 
668  // Create the stringstream
669  stringstream sout;
670  int exit_code = -1;
671 
672 #ifndef _WIN32
673  // Run Popen
674  FILE* in;
675  char buff[512];
676 
677  // Test output
678  if (!(in = popen(command.c_str(), mode.c_str())))
679  {
680  sout << "Popen Execution failed!" << endl;
681  *output = sout.str();
682 
683  return -1;
684  }
685 
686  // Parse output
687  while (fgets(buff, sizeof(buff), in) != nullptr)
688  {
689  sout << buff;
690  }
691 
692  // Close
693  exit_code = pclose(in);
694 #else
695  try
696  {
697  exit_code = -1;
698 
699  HANDLE g_hChildStd_IN_Rd = NULL;
700  HANDLE g_hChildStd_IN_Wr = NULL;
701  HANDLE g_hChildStd_OUT_Rd = NULL;
702  HANDLE g_hChildStd_OUT_Wr = NULL;
703 
704  HANDLE g_hInputFile = NULL;
705  SECURITY_ATTRIBUTES saAttr;
706  // Set the bInheritHandle flag so pipe handles are inherited.
707  saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
708  saAttr.bInheritHandle = TRUE;
709  saAttr.lpSecurityDescriptor = NULL;
710  // Create a pipe for the child process's STDOUT.
711  if (!CreatePipe(&g_hChildStd_OUT_Rd, &g_hChildStd_OUT_Wr, &saAttr, 0))
712  throw winerror2str("StdoutRd CreatePipe");
713 
714  // Ensure the read handle to the pipe for STDOUT is not inherited.
715 
716  if (!SetHandleInformation(g_hChildStd_OUT_Rd, HANDLE_FLAG_INHERIT, 0))
717  throw winerror2str("Stdout SetHandleInformation");
718 
719  // Create a pipe for the child process's STDIN.
720 
721  if (!CreatePipe(&g_hChildStd_IN_Rd, &g_hChildStd_IN_Wr, &saAttr, 0))
722  throw winerror2str("Stdin CreatePipe");
723 
724  // Ensure the write handle to the pipe for STDIN is not inherited.
725 
726  if (!SetHandleInformation(g_hChildStd_IN_Wr, HANDLE_FLAG_INHERIT, 0))
727  throw winerror2str("Stdin SetHandleInformation");
728 
729  // Create the child process:
730  PROCESS_INFORMATION piProcInfo;
731  STARTUPINFOA siStartInfo;
732  BOOL bSuccess = FALSE;
733 
734  // Set up members of the PROCESS_INFORMATION structure.
735 
736  ZeroMemory(&piProcInfo, sizeof(PROCESS_INFORMATION));
737 
738  // Set up members of the STARTUPINFO structure.
739  // This structure specifies the STDIN and STDOUT handles for
740  // redirection.
741 
742  ZeroMemory(&siStartInfo, sizeof(STARTUPINFO));
743  siStartInfo.cb = sizeof(STARTUPINFO);
744  siStartInfo.hStdError = g_hChildStd_OUT_Wr;
745  siStartInfo.hStdOutput = g_hChildStd_OUT_Wr;
746  siStartInfo.hStdInput = g_hChildStd_IN_Rd;
747  siStartInfo.dwFlags |= STARTF_USESTDHANDLES;
748 
749  // Create the child process.
750  bSuccess = CreateProcessA(
751  NULL,
752  (LPSTR)command.c_str(), // command line
753  NULL, // process security attributes
754  NULL, // primary thread security attributes
755  TRUE, // handles are inherited
756  0, // creation flags
757  NULL, // use parent's environment
758  NULL, // use parent's current directory
759  &siStartInfo, // STARTUPINFO pointer
760  &piProcInfo); // receives PROCESS_INFORMATION
761 
762  // If an error occurs, exit the application.
763  if (!bSuccess) throw winerror2str("CreateProcess");
764 
765  // Read from pipe that is the standard output for child process.
766  DWORD dwRead;
767  CHAR chBuf[4096];
768  bSuccess = FALSE;
769  DWORD exitval = 0;
770  exit_code = 0;
771  for (;;)
772  {
773  DWORD dwAvailable = 0;
774  PeekNamedPipe(
775  g_hChildStd_OUT_Rd, NULL, NULL, NULL, &dwAvailable, NULL);
776  if (dwAvailable)
777  {
778  bSuccess = ReadFile(
779  g_hChildStd_OUT_Rd, chBuf, sizeof(chBuf), &dwRead, NULL);
780  if (!bSuccess || dwRead == 0) break;
781  sout.write(chBuf, dwRead);
782  }
783  else
784  {
785  // process ended?
786  if (GetExitCodeProcess(piProcInfo.hProcess, &exitval))
787  {
788  if (exitval != STILL_ACTIVE)
789  {
790  exit_code = exitval;
791  break;
792  }
793  }
794  }
795  }
796 
797  // Close handles to the child process and its primary thread.
798  CloseHandle(piProcInfo.hProcess);
799  CloseHandle(piProcInfo.hThread);
800  }
801  catch (std::string& errStr)
802  {
803  std::cerr << errStr;
804  return 1; // !=0 means error
805  }
806 #endif
807  // set output - if valid pointer given
808  if (output)
809  {
810  *output = sout.str();
811  }
812 
813  // Return exit code
814  return exit_code;
815 } // end of executeCommand
const char * sLicenseTextF
Definition: os.cpp:526
#define THROW_EXCEPTION(msg)
Definition: exceptions.h:67
int getch() noexcept
An OS-independent version of getch, which waits until a key is pushed.
Definition: os.cpp:372
std::string std::string format(std::string_view fmt, ARGS &&... args)
Definition: format.h:26
int _strncmp(const char *str, const char *subStr, size_t count) noexcept
An OS-independent version of strncmp.
Definition: os.cpp:338
int void fclose(FILE *f)
An OS-independent version of fclose.
Definition: os.cpp:275
time_t timegm(struct tm *tm)
An OS-independent version of timegm (which is not present in all compilers): converts a time structur...
Definition: os.cpp:112
int _strnicmp(const char *str, const char *subStr, size_t count) noexcept
An OS-independent version of strnicmp.
Definition: os.cpp:346
void setConsoleColor(TConsoleColor color, bool changeStdErr=false)
Changes the text color in the console for the text written from now on.
Definition: os.cpp:484
mrpt::system::TTimeStamp now()
A shortcut for system::getCurrentTime.
Definition: datetime.h:86
STL namespace.
std::string MRPT_getCompilationDate()
Returns the MRPT source code timestamp, according to the Reproducible-Builds specifications: https://...
Definition: os.cpp:154
std::string find_mrpt_shared_dir()
Finds the "[MRPT]/share/mrpt/" directory, if available in the system.
Definition: os.cpp:613
std::string winerror2str(const char *errorPlaceName)
Definition: os.cpp:566
void clearConsole()
Clears the console window.
Definition: os.cpp:441
TConsoleColor
For use in setConsoleColor.
Definition: os.h:162
int fprintf(FILE *fil, const char *format,...) noexcept MRPT_printf_format_check(2
An OS-independent version of fprintf.
Definition: os.cpp:410
void pause(const std::string &msg=std::string("Press any key to continue...")) noexcept
Shows the message "Press any key to continue" (or other custom message) to the current standard outpu...
Definition: os.cpp:432
int executeCommand(const std::string &command, std::string *output=nullptr, const std::string &mode="r")
Execute Generic Shell Command.
Definition: os.cpp:662
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
int vsnprintf(char *buf, size_t bufSize, const char *format, va_list args) noexcept
An OS-independent version of vsnprintf (Notice the bufSize param, which may be ignored in some compil...
Definition: os.cpp:230
int int vsprintf(char *buf, size_t bufSize, const char *format, va_list args) noexcept
An OS-independent version of vsprintf (Notice the bufSize param, which may be ignored in some compile...
Definition: os.cpp:214
char * strcat(char *dest, size_t destSize, const char *source) noexcept
An OS-independent version of strcat.
Definition: os.cpp:284
bool kbhit() noexcept
An OS-independent version of kbhit, which returns true if a key has been pushed.
Definition: os.cpp:394
uint64_t _strtoull(const char *nptr, char **endptr, int base)
An OS-independent version of strtoull.
Definition: os.cpp:468
FILE * fopen(const char *fileName, const char *mode) noexcept
An OS-independent version of fopen.
Definition: os.cpp:257
bool directoryExists(const std::string &fileName)
Test if a given directory exists (it fails if the given path refers to an existing file)...
Definition: filesystem.cpp:137
std::string MRPT_getVersion()
Returns a string describing the MRPT version.
Definition: os.cpp:187
int64_t _strtoll(const char *nptr, char **endptr, int base)
An OS-independent version of strtoll.
Definition: os.cpp:456
char * strcpy(char *dest, size_t destSize, const char *source) noexcept
An OS-independent version of strcpy.
Definition: os.cpp:299
bool launchProcess(const std::string &command)
Executes the given command (which may contain a program + arguments), and waits until it finishes...
Definition: os.cpp:583
const std::string & getMRPTLicense()
Returns a const ref to a text with the same text that appears at the beginning of each MRPT file (use...
Definition: os.cpp:543
std::string extractFileDirectory(const std::string &filePath)
Extract the whole path (the directory) of a filename from a complete path plus name plus extension...
Definition: filesystem.cpp:78
int _strcmp(const char *str1, const char *str2) noexcept
An OS-independent version of strcmp.
Definition: os.cpp:314
int sprintf(char *buf, size_t bufSize, const char *format,...) noexcept MRPT_printf_format_check(3
An OS-independent version of sprintf (Notice the bufSize param, which may be ignored in some compiler...
Definition: os.cpp:191
void memcpy(void *dest, size_t destSize, const void *src, size_t copyCount) noexcept
An OS and compiler independent version of "memcpy".
Definition: os.cpp:358
#define MRPT_UNUSED_PARAM(a)
Determines whether this is an X86 or AMD64 platform.
Definition: common.h:186
int _strcmpi(const char *str1, const char *str2) noexcept
An OS-independent version of strcmpi.
Definition: os.cpp:322



Page generated by Doxygen 1.8.14 for MRPT 1.9.9 Git: 3a26b90fd Wed Mar 25 20:17:03 2020 +0100 at miƩ mar 25 23:05:41 CET 2020