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