2
0

childprocess.c 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. #include <SDL3/SDL.h>
  2. #include <SDL3/SDL_main.h>
  3. #include <SDL3/SDL_test.h>
  4. #ifdef SDL_PLATFORM_WINDOWS
  5. #include <io.h>
  6. #include <fcntl.h>
  7. #endif
  8. #include <stdio.h>
  9. #include <errno.h>
  10. int main(int argc, char *argv[]) {
  11. SDLTest_CommonState *state;
  12. int i;
  13. bool print_arguments = false;
  14. bool print_environment = false;
  15. bool stdin_to_stdout = false;
  16. bool read_stdin = false;
  17. bool stdin_to_stderr = false;
  18. SDL_IOStream *log_stdin = NULL;
  19. int exit_code = 0;
  20. state = SDLTest_CommonCreateState(argv, 0);
  21. for (i = 1; i < argc;) {
  22. int consumed = SDLTest_CommonArg(state, i);
  23. if (!consumed) {
  24. if (SDL_strcmp(argv[i], "--print-arguments") == 0) {
  25. print_arguments = true;
  26. consumed = 1;
  27. } else if (SDL_strcmp(argv[i], "--print-environment") == 0) {
  28. print_environment = true;
  29. consumed = 1;
  30. } else if (SDL_strcmp(argv[i], "--stdin-to-stdout") == 0) {
  31. stdin_to_stdout = true;
  32. consumed = 1;
  33. } else if (SDL_strcmp(argv[i], "--stdin-to-stderr") == 0) {
  34. stdin_to_stderr = true;
  35. consumed = 1;
  36. } else if (SDL_strcmp(argv[i], "--stdin") == 0) {
  37. read_stdin = true;
  38. consumed = 1;
  39. } else if (SDL_strcmp(argv[i], "--stdout") == 0) {
  40. if (i + 1 < argc) {
  41. fprintf(stdout, "%s", argv[i + 1]);
  42. consumed = 2;
  43. }
  44. } else if (SDL_strcmp(argv[i], "--stderr") == 0) {
  45. if (i + 1 < argc) {
  46. fprintf(stderr, "%s", argv[i + 1]);
  47. consumed = 2;
  48. }
  49. } else if (SDL_strcmp(argv[i], "--log-stdin") == 0) {
  50. if (i + 1 < argc) {
  51. log_stdin = SDL_IOFromFile(argv[i + 1], "w");
  52. if (!log_stdin) {
  53. fprintf(stderr, "Couldn't open %s\n", argv[i + 1]);
  54. return 2;
  55. }
  56. consumed = 2;
  57. }
  58. } else if (SDL_strcmp(argv[i], "--exit-code") == 0) {
  59. if (i + 1 < argc) {
  60. char *endptr = NULL;
  61. exit_code = SDL_strtol(argv[i + 1], &endptr, 0);
  62. if (endptr && *endptr == '\0') {
  63. consumed = 2;
  64. }
  65. }
  66. } else if (SDL_strcmp(argv[i], "--version") == 0) {
  67. int version = SDL_GetVersion();
  68. fprintf(stdout, "SDL version %d.%d.%d",
  69. SDL_VERSIONNUM_MAJOR(version),
  70. SDL_VERSIONNUM_MINOR(version),
  71. SDL_VERSIONNUM_MICRO(version));
  72. fprintf(stderr, "SDL version %d.%d.%d",
  73. SDL_VERSIONNUM_MAJOR(version),
  74. SDL_VERSIONNUM_MINOR(version),
  75. SDL_VERSIONNUM_MICRO(version));
  76. consumed = 1;
  77. break;
  78. } else if (SDL_strcmp(argv[i], "--") == 0) {
  79. i++;
  80. break;
  81. }
  82. }
  83. if (consumed <= 0) {
  84. const char *args[] = {
  85. "[--print-arguments]",
  86. "[--print-environment]",
  87. "[--stdin]",
  88. "[--log-stdin FILE]",
  89. "[--stdin-to-stdout]",
  90. "[--stdout TEXT]",
  91. "[--stdin-to-stderr]",
  92. "[--stderr TEXT]",
  93. "[--exit-code EXIT_CODE]",
  94. "[--] [ARG [ARG ...]]",
  95. NULL
  96. };
  97. SDLTest_CommonLogUsage(state, argv[0], args);
  98. return 1;
  99. }
  100. i += consumed;
  101. }
  102. if (print_arguments) {
  103. int print_i;
  104. #ifdef SDL_PLATFORM_WINDOWS
  105. /* reopen stdout as binary to prevent newline conversion */
  106. _setmode(_fileno(stdout), _O_BINARY);
  107. #endif
  108. for (print_i = 0; i + print_i < argc; print_i++) {
  109. fprintf(stdout, "|%d=%s|\r\n", print_i, argv[i + print_i]);
  110. }
  111. fflush(stdout);
  112. }
  113. if (print_environment) {
  114. char **env = SDL_GetEnvironmentVariables(SDL_GetEnvironment());
  115. if (env) {
  116. for (i = 0; env[i]; ++i) {
  117. fprintf(stdout, "%s\n", env[i]);
  118. }
  119. SDL_free(env);
  120. }
  121. fflush(stdout);
  122. }
  123. if (stdin_to_stdout || stdin_to_stderr || read_stdin) {
  124. for (;;) {
  125. char buffer[4 * 4096];
  126. size_t result;
  127. result = fread(buffer, 1, sizeof(buffer), stdin);
  128. if (result == 0) {
  129. if (!feof(stdin)) {
  130. char error[128];
  131. if (errno == EAGAIN) {
  132. clearerr(stdin);
  133. SDL_Delay(20);
  134. continue;
  135. }
  136. #ifdef SDL_PLATFORM_WINDOWS
  137. if (strerror_s(error, sizeof(error), errno) != 0) {
  138. SDL_strlcpy(error, "Unknown error", sizeof(error));
  139. }
  140. #else
  141. SDL_strlcpy(error, strerror(errno), sizeof(error));
  142. #endif
  143. SDL_Log("Error reading from stdin: %s", error);
  144. }
  145. break;
  146. }
  147. if (log_stdin) {
  148. SDL_WriteIO(log_stdin, buffer, result);
  149. SDL_FlushIO(log_stdin);
  150. }
  151. if (stdin_to_stdout) {
  152. fwrite(buffer, 1, result, stdout);
  153. fflush(stdout);
  154. }
  155. if (stdin_to_stderr) {
  156. fwrite(buffer, 1, result, stderr);
  157. }
  158. }
  159. }
  160. if (log_stdin) {
  161. SDL_CloseIO(log_stdin);
  162. }
  163. SDLTest_CommonDestroyState(state);
  164. return exit_code;
  165. }