int AG_Kill(AG_ProcessID pid) { #if defined(_WIN32) && !defined(_XBOX) HANDLE psHandle; #endif if(pid <= 0) { AG_SetError("Invalid process id"); return (-1); } #if defined(_WIN32) && !defined(_XBOX) if((psHandle = OpenProcess(SYNCHRONIZE | PROCESS_TERMINATE | PROCESS_QUERY_INFORMATION, FALSE, pid)) == NULL) { AG_SetError(_("Unable to obtain process handle (%s)"), AG_Strerror(GetLastError())); return -1; } if(TerminateProcess(psHandle, -1) == 0) { AG_SetError(_("Unable to kill process (%s)"), AG_Strerror(GetLastError())); return -1; } CloseHandle(psHandle); return (0); #elif defined(_MK_HAVE_SIGNAL) if (kill(pid, SIGKILL) == -1) { AG_SetError(_("Failed to kill process (%s)"), AG_Strerror(errno)); return (-1); } return (0); #endif AG_SetError("AG_Kill() is not supported on this platform"); return (-1); }
static int SaveToCSV(AG_Event *event) { struct test_ops *test = AG_PTR(1); AG_Table *t = AG_PTR(2); char separator = AG_UCHAR(3); char *path = AG_STRING(4); FILE *f; if ((f = fopen(path, "w")) == NULL) { AG_SetError("%s: Unable to open", AG_Strerror(errno)); return (-1); } fprintf(f, "Benchmark for Agar %d.%d.%d\n", AGAR_MAJOR_VERSION, AGAR_MINOR_VERSION, AGAR_PATCHLEVEL); fprintf(f, "Test: %s%s\n", test->name, (test->flags&TEST_SDL) ? " (SDL-only)" : (test->flags&TEST_GL) ? " (GL-only)" : ""); fprintf(f, "Iterations: %u x %u\n\n", test->runs, test->iterations); AG_TableSaveASCII(t, f, ':'); fclose(f); return (0); }
AG_ProcessID AG_Execute(const char *file, char **argv) { #ifdef _XBOX AG_LAUNCH_DATA launchData = { LDT_TITLE }; char xbePath[AG_PATHNAME_MAX]; char xbeName[AG_FILENAME_MAX]; char argstr[AG_ARG_MAX]; char mntDev[AG_PATHNAME_MAX]; char *p; DWORD xbeID; int i = 0; if(!file) { AG_SetError("No file provided for execution."); return (-1); } /* Get the destination xbe path */ if(!argv || !argv[0] || (file && strcmp(file, argv[0]))) { p = (char *)file; } else { p = argv[0]; i++; } /* Handle the command-line parameters */ argstr[0] = '\0'; if(argv) { while(argv[i] != NULL) { if( (AG_ARG_MAX - strlen(argstr) < strlen(argv[i]) + 1) ) { AG_SetError(_("%s: Supplied command arguments exceed AG_ARG_MAX (%d)"), p, AG_ARG_MAX); return (-1); } Strlcat(argstr, argv[i], AG_ARG_MAX); Strlcat(argstr, " ", AG_ARG_MAX); i++; } Strlcpy(launchData.szCmdLine, argstr, AG_ARG_MAX); } /* Resolve the full xbe path */ if((strlen(p) >= 7) && (!strncmp(p, "\\Device", 7))) { /* The xbe path was passed with the partition mapping */ Strlcpy(xbePath, p, AG_PATHNAME_MAX); } else { char drive[3]; char *dev; if(strlen(p) > 3 && isalpha(p[0]) && p[1] == ':' && p[2] == AG_PATHSEPCHAR) { /* The xbe path was passed with a drive letter */ Strlcpy(drive, p, sizeof(drive)); p = &p[3]; } else { /* Path is relative */ Strlcpy(drive, "D:", sizeof(drive)); } if((dev = AG_XBOX_GetDeviceFromLogicalDrive(drive)) == NULL) { AG_SetError("Invalid or unsupported drive letter." " Please provide a valid drive letter or the full device path."); return (-1); } Strlcpy(xbePath, dev, sizeof(xbePath)); if(xbePath[strlen(xbePath) - 1] != AG_PATHSEPCHAR && p[0] != AG_PATHSEPCHAR) Strlcat(xbePath, AG_PATHSEP, sizeof(xbePath)); Strlcat(xbePath, p, sizeof(xbePath)); Free(dev); } /* Isolate the xbe name */ p = strrchr(xbePath, '\\') + 1; if(!p) { AG_SetError("No XBE Name included with path"); return (-1); } Strlcpy(xbeName, p, AG_FILENAME_MAX); /* mntDev will be the D: path for the new xbe */ Strlcpy(mntDev, xbePath, p - xbePath); mntDev[p - xbePath] = '\0'; /* Get the xbe ID */ if((xbeID = AG_XBOX_GetXbeTitleId(xbePath)) == -1) { AG_SetError("XBE is invalid or currupted"); return (-1); } /* Complete the launch data */ Strlcpy(launchData.szLauncherXBE, XeImageFileName->Buffer, XeImageFileName->Length + 1); Strlcpy(launchData.szLaunchedXBE, xbePath, sizeof(xbePath)); /* Get the launcher ID */ launchData.dwID = AG_XBOX_GetXbeTitleId(launchData.szLauncherXBE); launchData.magic = AG_LAUNCH_MAGIC; /* If this call succeeds the Agar application will be terminated so any configs need to be saved prior to this call. */ XWriteTitleInfoAndRebootA(xbeName, mntDev, LDT_TITLE, xbeID, &launchData); /* If we are here an error occurred */ AG_SetError("XWriteTitleInfoAndRebootA failed."); return (-1); #elif defined(_WIN32) STARTUPINFOA si; PROCESS_INFORMATION pi; char argstr[AG_ARG_MAX]; int i = 0; if(!file) { AG_SetError("No file provided for execution."); return (-1); } ZeroMemory(&si, sizeof(si)); si.cb = sizeof(si); ZeroMemory(&pi, sizeof(pi)); if(file && strncmp(file, argv[0], strlen(file))) { strcpy(argstr, file); strcat(argstr, " "); } else { strcpy(argstr, argv[0]); strcat(argstr, " "); i++; } // Add the command-line parameters while(argv[i] != NULL) { if( (AG_ARG_MAX - strlen(argstr) < strlen(argv[i]) + 1) ) { AG_SetError(_("%s: Supplied command arguments exceed AG_ARG_MAX (%d)"), file, AG_ARG_MAX); return (-1); } strcat(argstr, argv[i]); strcat(argstr, " "); i++; } if(CreateProcessA(NULL, argstr, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi) == 0) { AG_SetError(_("Failed to execute (%s)"), AG_Strerror(GetLastError())); return (-1); } CloseHandle(pi.hThread); CloseHandle(pi.hProcess); return (pi.dwProcessId); #elif defined(HAVE_EXECVP) && !defined(_WIN32) AG_ProcessID pid; if(!file) { AG_SetError("No file provided for execution."); return (-1); } if((pid = fork()) == -1) { AG_SetError(_("Fork failed (%s)"), AG_Strerror(errno)); return (-1); } else if(pid == 0) { execvp(file, argv); // If we get here an error occurred _exit(EXIT_FAILURE); } else { return (pid); } #endif AG_SetError("AG_Execute() is not supported on this platform"); return (-1); }
AG_ProcessID AG_WaitOnProcess(AG_ProcessID pid, enum ag_exec_wait_type wait_t) { #if defined(_WIN32) && !defined(_XBOX) int time = 0; int res; DWORD status; HANDLE psHandle; if(wait_t == AG_EXEC_WAIT_INFINITE) { time = INFINITE; } if((psHandle = OpenProcess(SYNCHRONIZE | PROCESS_QUERY_INFORMATION, FALSE, pid)) == NULL) { AG_SetError(_("Unable to obtain process handle (%s)"), AG_Strerror(GetLastError())); return -1; } res = WaitForSingleObject(psHandle, time); if(res) { if(res == WAIT_TIMEOUT) { return 0; } else if(res == WAIT_FAILED) { AG_SetError(_("Wait on process failed (%s)"), AG_Strerror(GetLastError())); return -1; } } if(GetExitCodeProcess(psHandle, &status) == 0) { AG_SetError(_("Failed to obtain process exit code (%s)"), AG_Strerror(GetLastError())); return -1; } else if(status) { AG_SetError(_("Process exited with status (%d)"), (int)status); return -1; } CloseHandle(psHandle); return (pid); #elif defined(HAVE_EXECVP) && !defined(_WIN32) int res; int status; int options = 0; if(wait_t == AG_EXEC_WAIT_IMMEDIATE) { options = WNOHANG; } res = waitpid(pid, &status, options); if(res == -1) { AG_SetError(_("waitpid() failed with error (%s)"), AG_Strerror(errno)); return (-1); } else if(res > 0 && status) { if(WIFEXITED(status)) { AG_SetError(_("Process exited with status (%d)"), WEXITSTATUS(status)); } else if(WIFSIGNALED(status)) { AG_SetError(_("Process terminated by signal (%d)"), WTERMSIG(status)); } else { AG_SetError("Process exited for unknown reason"); } return (-1); } return (res); #endif AG_SetError("AG_WaitOnProcess() is not supported on this platform"); return (-1); }