visualtest/src/linux/linux_process.c
author Sam Lantinga <slouken@libsdl.org>
Thu, 07 Jun 2018 17:07:05 -0700
changeset 12013 270e17c85d11
parent 7924 fcb86d323770
permissions -rw-r--r--
Don't crash on exit from SDLActivity if we don't have a singleton for some reason. (Thanks Rachel!)
     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 
    22 static void
    23 LogLastError(char* str)
    24 {
    25     char* error = (char*)strerror(errno);
    26     if(!str || !error)
    27     	return;
    28     SDLTest_LogError("%s: %s", str, error);
    29 }
    30 
    31 int
    32 SDL_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 
    72 int
    73 SDL_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 
   105 int
   106 SDL_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 
   130 int
   131 SDL_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 
   165 int
   166 SDL_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