增加不限制时间和内存的选项

This commit is contained in:
virusdefender 2016-03-31 19:24:07 +08:00
parent 4315efac56
commit 2577bec965
5 changed files with 53 additions and 27 deletions

View File

@ -9,8 +9,8 @@ def _compile():
return judger.run(path="/usr/bin/gcc",
in_file=os.path.join(base_path, "in"),
out_file=os.path.join(base_path, "gcc_out"),
max_cpu_time=2000,
max_memory=200000000,
max_cpu_time=judger.CPU_TIME_UNLIMITED,
max_memory=judger.MEMORY_UNLIMITED,
args=[os.path.join(base_path, "demo.c"), "-o", os.path.join(base_path, "demo")],
env=["PATH=" + os.environ["PATH"]],
use_sandbox=False,

View File

@ -20,12 +20,12 @@ static PyObject *judger_run(PyObject *self, PyObject *args, PyObject *kwargs) {
PyErr_SetString(PyExc_ValueError, "Invalid args and kwargs");
return NULL;
}
if (config.max_cpu_time <= 1) {
PyErr_SetString(PyExc_ValueError, "max_cpu_time must > 1 ms");
if (config.max_cpu_time < 1 && config.max_cpu_time != CPU_TIME_UNLIMITED) {
PyErr_SetString(PyExc_ValueError, "max_cpu_time must > 1 ms or unlimited");
return NULL;
}
if (config.max_memory < 16 * 1024 * 1024) {
PyErr_SetString(PyExc_ValueError, "max_memory must > 16M");
if (config.max_memory < 16 * 1024 * 1024 && config.max_memory != MEMORY_UNLIMITED) {
PyErr_SetString(PyExc_ValueError, "max_memory must > 16M or unlimited");
return NULL;
}
if (access(config.path, F_OK) == -1) {
@ -131,5 +131,7 @@ static PyMethodDef judger_methods[] = {
PyMODINIT_FUNC initjudger(void) {
Py_InitModule3("judger", judger_methods, NULL);
PyObject *module = Py_InitModule3("judger", judger_methods, NULL);
PyModule_AddIntConstant(module, "CPU_TIME_UNLIMITED", CPU_TIME_UNLIMITED);
PyModule_AddIntConstant(module, "MEMORY_UNLIMITED", MEMORY_UNLIMITED);
}

View File

@ -55,13 +55,13 @@ void run(struct config *config, struct result *result) {
gettimeofday(&start, NULL);
if(config->max_memory < 1) {
LOG_FATAL("memory can not be less than 1");
if(config->max_memory < 1 && config->max_memory != MEMORY_UNLIMITED) {
LOG_FATAL("max_memory must > 1 or unlimited");
result->flag = SYSTEM_ERROR;
return;
}
if(config->max_cpu_time < 1) {
LOG_FATAL("cpu time can not be less than 1");
if(config->max_cpu_time < 1 && config->max_cpu_time != CPU_TIME_UNLIMITED) {
LOG_FATAL("max_cpu_time must > 1 or unlimited");
result->flag = SYSTEM_ERROR;
return;
}
@ -74,7 +74,6 @@ void run(struct config *config, struct result *result) {
return;
}
memory_limit.rlim_cur = memory_limit.rlim_max = (rlim_t) (config->max_memory) * 2;
pid_t pid = fork();
@ -155,19 +154,24 @@ void run(struct config *config, struct result *result) {
// child process
// On success, these system calls return 0.
// On error, -1 is returned, and errno is set appropriately.
if (setrlimit(RLIMIT_AS, &memory_limit) == -1) {
LOG_FATAL("setrlimit failed, errno: %d", errno);
ERROR(SETRLIMIT_FAILED);
if (config->max_memory != MEMORY_UNLIMITED) {
memory_limit.rlim_cur = memory_limit.rlim_max = (rlim_t) (config->max_memory) * 2;
if (setrlimit(RLIMIT_AS, &memory_limit) == -1) {
LOG_FATAL("setrlimit failed, errno: %d", errno);
ERROR(SETRLIMIT_FAILED);
}
}
// cpu time
if (set_timer(config->max_cpu_time / 1000, config->max_cpu_time % 1000, 1) != SUCCESS) {
LOG_FATAL("set cpu time timer failed");
ERROR(SETITIMER_FAILED);
}
// real time * 3
if (set_timer(config->max_cpu_time / 1000 * 3, (config->max_cpu_time % 1000) * 3 % 1000, 0) != SUCCESS) {
LOG_FATAL("set real time timer failed");
ERROR(SETITIMER_FAILED);
if (config->max_cpu_time != CPU_TIME_UNLIMITED) {
// cpu time
if (set_timer(config->max_cpu_time / 1000, config->max_cpu_time % 1000, 1) != SUCCESS) {
LOG_FATAL("set cpu time timer failed");
ERROR(SETITIMER_FAILED);
}
// real time * 3
if (set_timer(config->max_cpu_time / 1000 * 3, (config->max_cpu_time % 1000) * 3 % 1000, 0) != SUCCESS) {
LOG_FATAL("set real time timer failed");
ERROR(SETITIMER_FAILED);
}
}
// read stdin from in file

View File

@ -2,6 +2,11 @@
#define JUDGER_RUNNER_H
#endif
#define CPU_TIME_UNLIMITED -1
#define MEMORY_UNLIMITED -1
#define SUCCESS 0
#define FORK_FAILED 1
@ -15,12 +20,14 @@
#define SET_UID_FAILED 9
#define SET_GID_FAILED 10
#define CPU_TIME_LIMIT_EXCEEDED 1
#define REAL_TIME_LIMIT_EXCEEDED 2
#define MEMORY_LIMIT_EXCEEDED 3
#define RUNTIME_ERROR 4
#define SYSTEM_ERROR 5
#define ERROR(code) LOG_FATAL("judger return error code: %d", code);raise(SIGUSR1)

View File

@ -54,16 +54,29 @@ class JudgerTest(TestCase):
self._judger_user_args_check()
def _judger_cpu_time_args_check(self):
with self.assertRaisesRegexp(ValueError, "max_cpu_time must > 1 ms"):
with self.assertRaisesRegexp(ValueError, "max_cpu_time must > 1 ms or unlimited"):
judger.run(path="/bin/true", in_file="/dev/null",
out_file="/dev/null", max_cpu_time=-1, max_memory=200000000,
out_file="/dev/null", max_cpu_time=0, max_memory=200000000,
env=["aaa=123"], use_sandbox=False, use_nobody=False)
try:
judger.run(path="/bin/true", in_file="/dev/null",
out_file="/dev/null", max_cpu_time=judger.CPU_TIME_UNLIMITED, max_memory=200000000,
env=["aaa=123"], use_sandbox=False, use_nobody=False)
except Exception as e:
self.fail(e.message)
def _judger_memory_args_check(self):
with self.assertRaisesRegexp(ValueError, "max_memory must > 16M"):
with self.assertRaisesRegexp(ValueError, "max_memory must > 16M or unlimited"):
judger.run(path="/bin/true", in_file="/dev/null",
out_file="/dev/null", max_cpu_time=1000, max_memory=100,
env=["aaa=123"], use_sandbox=True, use_nobody=True)
try:
judger.run(path="/bin/true", in_file="/dev/null",
out_file="/dev/null", max_cpu_time=1000, max_memory=judger.MEMORY_UNLIMITED,
env=["aaa=123"], use_sandbox=True, use_nobody=True)
except Exception as e:
self.fail(e.message)
def _judger_exec_file_args_check(self):
with self.assertRaisesRegexp(ValueError, "Exec file does not exist"):