linux_process.c 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  1. /* See COPYING.txt for the full license governing this code. */
  2. /**
  3. * \file linux_process.c
  4. *
  5. * Source file for the process API on linux.
  6. */
  7. #include <SDL.h>
  8. #include <SDL_test.h>
  9. #include <sys/types.h>
  10. #include <sys/wait.h>
  11. #include <unistd.h>
  12. #include <errno.h>
  13. #include "SDL_visualtest_process.h"
  14. #include "SDL_visualtest_harness_argparser.h"
  15. #include "SDL_visualtest_parsehelper.h"
  16. #if defined(__LINUX__)
  17. static void
  18. LogLastError(char* str)
  19. {
  20. char* error = (char*)strerror(errno);
  21. if(!str || !error)
  22. return;
  23. SDLTest_LogError("%s: %s", str, error);
  24. }
  25. int
  26. SDL_LaunchProcess(char* file, char* args, SDL_ProcessInfo* pinfo)
  27. {
  28. pid_t pid;
  29. char** argv;
  30. if(!file)
  31. {
  32. SDLTest_LogError("file argument cannot be NULL");
  33. return 0;
  34. }
  35. if(!pinfo)
  36. {
  37. SDLTest_LogError("pinfo cannot be NULL");
  38. return 0;
  39. }
  40. pid = fork();
  41. if(pid == -1)
  42. {
  43. LogLastError("fork() failed");
  44. return 0;
  45. }
  46. else if(pid == 0)
  47. {
  48. /* parse the arguments string */
  49. argv = SDLVisualTest_ParseArgsToArgv(args);
  50. argv[0] = file;
  51. execv(file, argv);
  52. LogLastError("execv() failed");
  53. return 0;
  54. }
  55. else
  56. {
  57. pinfo->pid = pid;
  58. return 1;
  59. }
  60. /* never executed */
  61. return 0;
  62. }
  63. int
  64. SDL_GetProcessExitStatus(SDL_ProcessInfo* pinfo, SDL_ProcessExitStatus* ps)
  65. {
  66. int success, status;
  67. if(!pinfo)
  68. {
  69. SDLTest_LogError("pinfo argument cannot be NULL");
  70. return 0;
  71. }
  72. if(!ps)
  73. {
  74. SDLTest_LogError("ps argument cannot be NULL");
  75. return 0;
  76. }
  77. success = waitpid(pinfo->pid, &status, WNOHANG);
  78. if(success == -1)
  79. {
  80. LogLastError("waitpid() failed");
  81. return 0;
  82. }
  83. else if(success == 0)
  84. {
  85. ps->exit_status = -1;
  86. ps->exit_success = 1;
  87. }
  88. else
  89. {
  90. ps->exit_success = WIFEXITED(status);
  91. ps->exit_status = WEXITSTATUS(status);
  92. }
  93. return 1;
  94. }
  95. int
  96. SDL_IsProcessRunning(SDL_ProcessInfo* pinfo)
  97. {
  98. int success;
  99. if(!pinfo)
  100. {
  101. SDLTest_LogError("pinfo cannot be NULL");
  102. return -1;
  103. }
  104. success = kill(pinfo->pid, 0);
  105. if(success == -1)
  106. {
  107. if(errno == ESRCH) /* process is not running */
  108. return 0;
  109. else
  110. {
  111. LogLastError("kill() failed");
  112. return -1;
  113. }
  114. }
  115. return 1;
  116. }
  117. int
  118. SDL_QuitProcess(SDL_ProcessInfo* pinfo, SDL_ProcessExitStatus* ps)
  119. {
  120. int success, status;
  121. if(!pinfo)
  122. {
  123. SDLTest_LogError("pinfo argument cannot be NULL");
  124. return 0;
  125. }
  126. if(!ps)
  127. {
  128. SDLTest_LogError("ps argument cannot be NULL");
  129. return 0;
  130. }
  131. success = kill(pinfo->pid, SIGQUIT);
  132. if(success == -1)
  133. {
  134. LogLastError("kill() failed");
  135. return 0;
  136. }
  137. success = waitpid(pinfo->pid, &status, 0);
  138. if(success == -1)
  139. {
  140. LogLastError("waitpid() failed");
  141. return 0;
  142. }
  143. ps->exit_success = WIFEXITED(status);
  144. ps->exit_status = WEXITSTATUS(status);
  145. return 1;
  146. }
  147. int
  148. SDL_KillProcess(SDL_ProcessInfo* pinfo, SDL_ProcessExitStatus* ps)
  149. {
  150. int success, status;
  151. if(!pinfo)
  152. {
  153. SDLTest_LogError("pinfo argument cannot be NULL");
  154. return 0;
  155. }
  156. if(!ps)
  157. {
  158. SDLTest_LogError("ps argument cannot be NULL");
  159. return 0;
  160. }
  161. success = kill(pinfo->pid, SIGKILL);
  162. if(success == -1)
  163. {
  164. LogLastError("kill() failed");
  165. return 0;
  166. }
  167. success = waitpid(pinfo->pid, &status, 0);
  168. if(success == -1)
  169. {
  170. LogLastError("waitpid() failed");
  171. return 0;
  172. }
  173. ps->exit_success = WIFEXITED(status);
  174. ps->exit_status = WEXITSTATUS(status);
  175. return 1;
  176. }
  177. #endif