melder_sysenv.cpp 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. /* melder_sysenv.cpp
  2. *
  3. * Copyright (C) 1992-2007,2011,2012,2015-2018 Paul Boersma
  4. *
  5. * This code is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation; either version 2 of the License, or (at
  8. * your option) any later version.
  9. *
  10. * This code is distributed in the hope that it will be useful, but
  11. * WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  13. * See the GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with this work. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. /*
  19. * pb 2004/10/14 made Cygwin-compatible
  20. * Eric Carlson & Paul Boersma 2005/05/19 made MinGW-compatible
  21. * pb 2006/10/28 erased MacOS 9 stuff
  22. * pb 2011/04/05 C++
  23. */
  24. #if defined (_WIN32)
  25. #if ! defined (__CYGWIN__) && ! defined (__MINGW32__)
  26. #include <crtl.h>
  27. #endif
  28. #include <windows.h>
  29. #include <errno.h>
  30. #include <stdlib.h>
  31. #else
  32. #if defined (linux)
  33. #include <sys/wait.h>
  34. #endif
  35. #include <unistd.h>
  36. #include <sys/types.h>
  37. #include <sys/wait.h>
  38. #endif
  39. #include "melder.h"
  40. conststring32 Melder_getenv (conststring32 variableName) {
  41. #if defined (macintosh) || defined (UNIX) || defined (__MINGW32__) || defined (__CYGWIN__)
  42. return Melder_peek8to32 (getenv (Melder_peek32to8 (variableName)));
  43. #elif defined (_WIN32)
  44. static char32 buffer [11] [255];
  45. static int ibuffer = 0;
  46. if (++ ibuffer == 11) ibuffer = 0;
  47. DWORD n = GetEnvironmentVariableW (variableName, buffer [ibuffer], 255); BUG
  48. if (n == ERROR_ENVVAR_NOT_FOUND) return nullptr;
  49. return & buffer [ibuffer] [0];
  50. #else
  51. return nullptr;
  52. #endif
  53. }
  54. void Melder_system (conststring32 command) {
  55. if (! command) command = U"";
  56. #if defined (macintosh) || defined (UNIX)
  57. if (system (Melder_peek32to8 (command)) != 0)
  58. Melder_throw (U"System command failed.");
  59. #elif defined (_WIN32)
  60. STARTUPINFO siStartInfo;
  61. PROCESS_INFORMATION piProcInfo;
  62. conststring32 comspec = Melder_getenv (U"COMSPEC"); // e.g. "C:\WINDOWS\COMMAND.COM" or "C:\WINNT\windows32\cmd.exe"
  63. if (! comspec)
  64. comspec = Melder_getenv (U"ComSpec");
  65. autoMelderString buffer;
  66. if (comspec) {
  67. MelderString_copy (& buffer, comspec);
  68. } else {
  69. OSVERSIONINFOEX osVersionInfo;
  70. memset (& osVersionInfo, 0, sizeof (OSVERSIONINFOEX));
  71. osVersionInfo. dwOSVersionInfoSize = sizeof (OSVERSIONINFOEX);
  72. if (! GetVersionEx ((OSVERSIONINFO *) & osVersionInfo)) {
  73. osVersionInfo. dwOSVersionInfoSize = sizeof (OSVERSIONINFO);
  74. if (! GetVersionEx ((OSVERSIONINFO *) & osVersionInfo))
  75. Melder_throw (U"System command cannot find system version.");
  76. }
  77. switch (osVersionInfo. dwPlatformId) {
  78. case VER_PLATFORM_WIN32_NT: {
  79. MelderString_copy (& buffer, U"cmd.exe");
  80. } break; case VER_PLATFORM_WIN32_WINDOWS: {
  81. MelderString_copy (& buffer, U"command.com");
  82. } break; default: {
  83. MelderString_copy (& buffer, U"command.com");
  84. }
  85. }
  86. }
  87. MelderString_append (& buffer, U" /c ", command);
  88. memset (& siStartInfo, 0, sizeof (siStartInfo));
  89. siStartInfo. cb = sizeof (siStartInfo);
  90. if (! CreateProcess (nullptr, (WCHAR *) Melder_peek32toW (buffer.string), nullptr, nullptr, true, CREATE_NO_WINDOW, nullptr, nullptr, & siStartInfo, & piProcInfo))
  91. Melder_throw (U"Cannot create subprocess.");
  92. WaitForSingleObject (piProcInfo. hProcess, -1);
  93. CloseHandle (piProcInfo. hProcess);
  94. CloseHandle (piProcInfo. hThread);
  95. #endif
  96. }
  97. void Melder_execv (conststring32 executableFileName, integer narg, char32 ** args) {
  98. #if defined (macintosh) || defined (UNIX)
  99. Melder_casual (U"Command: <<", executableFileName, U">>");
  100. autostring8vector args8 (narg + 2);
  101. args8 [1] = Melder_32to8 (executableFileName);
  102. for (integer i = 1; i <= narg; i ++) {
  103. Melder_casual (U"Argument ", i, U": <<", args [i], U">>");
  104. args8 [1 + i] = Melder_32to8 (args [i]);
  105. }
  106. args8 [narg + 2] = autostring8();
  107. pid_t processID = fork ();
  108. if (processID == 0) { // we are in the child process
  109. execvp (Melder_peek32to8 (executableFileName), & args8.peek2() [1]);
  110. /* if we arrive here, some error occurred */
  111. fprintf (stderr, "Some error occurred");
  112. _exit (EXIT_FAILURE);
  113. } else if (processID > 0) { // we are still in the calling Praat
  114. waitpid (processID, nullptr, 0);
  115. } else {
  116. Melder_throw (U"Could not fork.");
  117. }
  118. #elif defined (_WIN32)
  119. #endif
  120. }
  121. /* End of file melder_sysenv.cpp */