/* * undef USE_JOB_CONTROL on systems less than 2000,XP * These systems don't support this API, but as a consequence, * the running time won't be limited. */ #define USE_JOB_CONTROL /* This program is licensed under GPL v2. Written by: Johannes Berg Alexander Schremmer */ /* Usage: runlimit CPUTIME DIRECTORY EXECUTABLE [OPTS] This will run "EXECUTABLE OPTS" in the directory DIRECTORY. The process will be killed if it does not terminate in CPUTIME seconds. */ int main(int argc, char** argv) { char cmdlinebuffer[CMDLINE_MAX], cmdlinebuffer2[CMDLINE_MAX]; char* cmdline = NULL; STARTUPINFO startupinfo; PROCESS_INFORMATION processinfo; DWORD exitcode; unsigned int joblimit; /* need to parse parameter even if not using job limits */ #ifdef USE_JOB_CONTROL JOBOBJECT_BASIC_LIMIT_INFORMATION lpJobObjectInfo; DWORD cbJobObjectInfoLength = sizeof(JOBOBJECT_BASIC_LIMIT_INFORMATION); LARGE_INTEGER large_int; lpJobObjectInfo.LimitFlags = JOB_OBJECT_LIMIT_PROCESS_TIME; HANDLE job = CreateJobObject(NULL, NULL); if (job == NULL) { fprintf(stderr, "Failed to create job object\n"); return 2; } #endif startupinfo.cb = sizeof(STARTUPINFO); startupinfo.lpReserved=NULL; startupinfo.lpDesktop=NULL; startupinfo.lpTitle=NULL; startupinfo.dwFlags=0; startupinfo.wShowWindow=0; startupinfo.cbReserved2=0; startupinfo.lpReserved2=NULL; cmdlinebuffer[0] = '\0'; _dup2(1,2); if (argc < 3) return 2; /* bah. nothing to do */ joblimit = atoi(argv[1]); if (!joblimit) return 2; #ifdef USE_JOB_CONTROL large_int.QuadPart = 10000000 * joblimit; lpJobObjectInfo.PerProcessUserTimeLimit = large_int; #endif if (argc > 3) { _snprintf(cmdlinebuffer, CMDLINE_MAX-1, "\"%s\"", argv[3]); for (int i = 4; i < argc; i++) { memcpy(cmdlinebuffer2, cmdlinebuffer, CMDLINE_MAX); _snprintf(cmdlinebuffer, CMDLINE_MAX-1, "%s \"%s\"", cmdlinebuffer2, argv[i]); } cmdline = &cmdlinebuffer[0]; } if (!CreateProcess (NULL, cmdline, NULL, NULL, FALSE, CREATE_BREAKAWAY_FROM_JOB, NULL, argv[2], &startupinfo, &processinfo)) { fprintf(stderr, "CreateProcess failed: %i\n", GetLastError()); return 2; } else { CloseHandle(processinfo.hThread); } #ifdef USE_JOB_CONTROL if (!SetInformationJobObject(job, JobObjectBasicLimitInformation, &lpJobObjectInfo, cbJobObjectInfoLength)) { fprintf(stderr, "SetInformationJobObject failed, process running uncontrolled!\n"); } if (!AssignProcessToJobObject(job, processinfo.hProcess)) { fprintf(stderr, "AssignProcessToJobObject failed, process running uncontrolled!\n"); } #endif if (WaitForSingleObject(processinfo.hProcess, INFINITE) == WAIT_FAILED) { fprintf(stderr, "WaitForSingleObject failed with code %d\n", GetLastError()); } if (!GetExitCodeProcess(processinfo.hProcess, &exitcode)) { fprintf(stderr, "GetExitCodeProcess failed with %d\n", GetLastError()); exitcode = 2; } CloseHandle(processinfo.hProcess); #ifdef USE_JOB_CONTROL CloseHandle(job); #endif return exitcode; }