childprocess.c 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  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. #ifdef SDL_PLATFORM_WINDOWS
  7. #include <windows.h>
  8. #else
  9. #include <fcntl.h>
  10. #include <unistd.h>
  11. #endif
  12. int main(int argc, char *argv[]) {
  13. SDLTest_CommonState *state;
  14. int i;
  15. bool print_arguments = false;
  16. bool print_environment = false;
  17. bool stdin_to_stdout = false;
  18. bool read_stdin = false;
  19. bool stdin_to_stderr = false;
  20. int exit_code = 0;
  21. state = SDLTest_CommonCreateState(argv, 0);
  22. for (i = 1; i < argc;) {
  23. int consumed = SDLTest_CommonArg(state, i);
  24. if (!consumed) {
  25. if (SDL_strcmp(argv[i], "--print-arguments") == 0) {
  26. print_arguments = true;
  27. consumed = 1;
  28. } else if (SDL_strcmp(argv[i], "--print-environment") == 0) {
  29. print_environment = true;
  30. consumed = 1;
  31. } else if (SDL_strcmp(argv[i], "--stdin-to-stdout") == 0) {
  32. stdin_to_stdout = true;
  33. consumed = 1;
  34. } else if (SDL_strcmp(argv[i], "--stdin-to-stderr") == 0) {
  35. stdin_to_stderr = true;
  36. consumed = 1;
  37. } else if (SDL_strcmp(argv[i], "--stdin") == 0) {
  38. read_stdin = true;
  39. consumed = 1;
  40. } else if (SDL_strcmp(argv[i], "--stdout") == 0) {
  41. if (i + 1 < argc) {
  42. fprintf(stdout, "%s", argv[i + 1]);
  43. consumed = 2;
  44. }
  45. } else if (SDL_strcmp(argv[i], "--stderr") == 0) {
  46. if (i + 1 < argc) {
  47. fprintf(stderr, "%s", argv[i + 1]);
  48. consumed = 2;
  49. }
  50. } else if (SDL_strcmp(argv[i], "--exit-code") == 0) {
  51. if (i + 1 < argc) {
  52. char *endptr = NULL;
  53. exit_code = SDL_strtol(argv[i + 1], &endptr, 0);
  54. if (endptr && *endptr == '\0') {
  55. consumed = 2;
  56. }
  57. }
  58. } else if (SDL_strcmp(argv[i], "--version") == 0) {
  59. int version = SDL_GetVersion();
  60. fprintf(stdout, "SDL version %d.%d.%d",
  61. SDL_VERSIONNUM_MAJOR(version),
  62. SDL_VERSIONNUM_MINOR(version),
  63. SDL_VERSIONNUM_MICRO(version));
  64. fprintf(stderr, "SDL version %d.%d.%d",
  65. SDL_VERSIONNUM_MAJOR(version),
  66. SDL_VERSIONNUM_MINOR(version),
  67. SDL_VERSIONNUM_MICRO(version));
  68. consumed = 1;
  69. break;
  70. } else if (SDL_strcmp(argv[i], "--") == 0) {
  71. i++;
  72. break;
  73. }
  74. }
  75. if (consumed <= 0) {
  76. const char *args[] = {
  77. "[--print-arguments]",
  78. "[--print-environment]",
  79. "[--stdin]",
  80. "[--stdin-to-stdout]",
  81. "[--stdout TEXT]",
  82. "[--stdin-to-stderr]",
  83. "[--stderr TEXT]",
  84. "[--exit-code EXIT_CODE]",
  85. "[--] [ARG [ARG ...]]",
  86. NULL
  87. };
  88. SDLTest_CommonLogUsage(state, argv[0], args);
  89. return 1;
  90. }
  91. i += consumed;
  92. }
  93. if (print_arguments) {
  94. int print_i;
  95. for (print_i = 0; i + print_i < argc; print_i++) {
  96. fprintf(stdout, "|%d=%s|\r\n", print_i, argv[i + print_i]);
  97. }
  98. }
  99. if (print_environment) {
  100. char **env = SDL_GetEnvironmentVariables(SDL_GetEnvironment());
  101. if (env) {
  102. for (i = 0; env[i]; ++i) {
  103. fprintf(stdout, "%s\n", env[i]);
  104. }
  105. SDL_free(env);
  106. }
  107. }
  108. #ifdef SDL_PLATFORM_WINDOWS
  109. {
  110. DWORD mode;
  111. HANDLE stdout_handle = GetStdHandle(STD_INPUT_HANDLE);
  112. GetConsoleMode(stdout_handle, &mode);
  113. SetConsoleMode(stdout_handle, mode & ~(ENABLE_LINE_INPUT));
  114. }
  115. #else
  116. fcntl(STDIN_FILENO, F_SETFL, fcntl(STDIN_FILENO, F_GETFL, 0) & ~(O_NONBLOCK));
  117. #endif
  118. if (stdin_to_stdout || stdin_to_stderr || read_stdin) {
  119. for (;;) {
  120. char buffer[4 * 4096];
  121. size_t result;
  122. result = fread(buffer, 1, sizeof(buffer), stdin);
  123. if (result == 0) {
  124. if (errno == EAGAIN) {
  125. clearerr(stdin);
  126. SDL_Delay(20);
  127. continue;
  128. }
  129. break;
  130. }
  131. if (stdin_to_stdout) {
  132. fwrite(buffer, 1, result, stdout);
  133. fflush(stdout);
  134. }
  135. if (stdin_to_stderr) {
  136. fwrite(buffer, 1, result, stderr);
  137. }
  138. }
  139. }
  140. SDLTest_CommonDestroyState(state);
  141. return exit_code;
  142. }