cscg22-gearboy

CSCG 2022 Challenge 'Gearboy'
git clone https://git.sinitax.com/sinitax/cscg22-gearboy
Log | Files | Refs | sfeed.txt

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