childprocess.c 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. #include <SDL3/SDL.h>
  2. #include <SDL3/SDL_main.h>
  3. #include <SDL3/SDL_test.h>
  4. #include <stdio.h>
  5. #include <errno.h>
  6. #if defined(SDL_PLATFORM_WINDOWS)
  7. #include <windows.h>
  8. #elif defined(SDL_PLATFORM_MACOS)
  9. #include <crt_externs.h>
  10. #define environ (*_NSGetEnviron())
  11. #else
  12. extern char **environ;
  13. #endif
  14. int main(int argc, char *argv[]) {
  15. SDLTest_CommonState *state;
  16. int i;
  17. const char *expect_environment = NULL;
  18. SDL_bool expect_environment_match = SDL_FALSE;
  19. SDL_bool print_arguments = SDL_FALSE;
  20. SDL_bool print_environment = SDL_FALSE;
  21. SDL_bool stdin_to_stdout = SDL_FALSE;
  22. SDL_bool stdin_to_stderr = SDL_FALSE;
  23. int exit_code = 0;
  24. state = SDLTest_CommonCreateState(argv, 0);
  25. for (i = 1; i < argc;) {
  26. int consumed = SDLTest_CommonArg(state, i);
  27. if (SDL_strcmp(argv[i], "--print-arguments") == 0) {
  28. print_arguments = SDL_TRUE;
  29. consumed = 1;
  30. } else if (SDL_strcmp(argv[i], "--print-environment") == 0) {
  31. print_environment = SDL_TRUE;
  32. consumed = 1;
  33. } else if (SDL_strcmp(argv[i], "--expect-env") == 0) {
  34. if (i + 1 < argc) {
  35. expect_environment = argv[i + 1];
  36. consumed = 2;
  37. }
  38. } else if (SDL_strcmp(argv[i], "--stdin-to-stdout") == 0) {
  39. stdin_to_stdout = SDL_TRUE;
  40. consumed = 1;
  41. } else if (SDL_strcmp(argv[i], "--stdin-to-stderr") == 0) {
  42. stdin_to_stderr = SDL_TRUE;
  43. consumed = 1;
  44. } else if (SDL_strcmp(argv[i], "--stdout") == 0) {
  45. if (i + 1 < argc) {
  46. fprintf(stdout, "%s", argv[i + 1]);
  47. consumed = 2;
  48. }
  49. } else if (SDL_strcmp(argv[i], "--stderr") == 0) {
  50. if (i + 1 < argc) {
  51. fprintf(stderr, "%s", argv[i + 1]);
  52. consumed = 2;
  53. }
  54. } else if (SDL_strcmp(argv[i], "--exit-code") == 0) {
  55. if (i + 1 < argc) {
  56. char *endptr = NULL;
  57. exit_code = SDL_strtol(argv[i + 1], &endptr, 0);
  58. if (endptr && *endptr == '\0') {
  59. consumed = 2;
  60. }
  61. }
  62. } else if (SDL_strcmp(argv[i], "--") == 0) {
  63. i++;
  64. break;
  65. }
  66. if (consumed <= 0) {
  67. const char *args[] = {
  68. "[--print-arguments]",
  69. "[--print-environment]",
  70. "[--expect-env KEY=VAL]",
  71. "[--stdin-to-stdout]",
  72. "[--stdout TEXT]",
  73. "[--stdin-to-stderr]",
  74. "[--stderr TEXT]",
  75. "[--exit-code EXIT_CODE]",
  76. "[--] [ARG [ARG ...]]",
  77. NULL
  78. };
  79. SDLTest_CommonLogUsage(state, argv[0], args);
  80. return 1;
  81. }
  82. i += consumed;
  83. }
  84. if (print_arguments) {
  85. int print_i;
  86. for (print_i = 0; i + print_i < argc; print_i++) {
  87. fprintf(stdout, "|%d=%s|\r\n", print_i, argv[i + print_i]);
  88. }
  89. }
  90. if (print_environment || expect_environment) {
  91. #if defined(SDL_PLATFORM_WINDOWS)
  92. char *original_env = GetEnvironmentStrings();
  93. const char *env = original_env;
  94. for (; env[0]; env += SDL_strlen(env) + 1) {
  95. #else
  96. char **envp = environ;
  97. for (; *envp; envp++) {
  98. const char *env = *envp;
  99. #endif
  100. if (print_environment) {
  101. fprintf(stdout, "%s\n", env);
  102. }
  103. if (expect_environment) {
  104. expect_environment_match |= SDL_strcmp(env, expect_environment) == 0;
  105. }
  106. }
  107. #ifdef SDL_PLATFORM_WINDOWS
  108. FreeEnvironmentStringsA(original_env);
  109. #endif
  110. }
  111. if (stdin_to_stdout || stdin_to_stderr) {
  112. for (;;) {
  113. int c;
  114. c = fgetc(stdin);
  115. if (c == EOF) {
  116. if (errno == EAGAIN) {
  117. clearerr(stdin);
  118. SDL_Delay(10);
  119. continue;
  120. }
  121. break;
  122. }
  123. if (stdin_to_stdout) {
  124. fputc(c, stdout);
  125. fflush(stdout);
  126. }
  127. if (stdin_to_stderr) {
  128. fputc(c, stderr);
  129. }
  130. }
  131. }
  132. SDLTest_CommonDestroyState(state);
  133. if (expect_environment && !expect_environment_match) {
  134. exit_code |= 0x1;
  135. }
  136. return exit_code;
  137. }