mirror of
https://github.com/QingdaoU/Judger.git
synced 2024-12-28 16:01:41 +00:00
增加不限制时间和内存的选项
This commit is contained in:
parent
4315efac56
commit
2577bec965
@ -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,
|
||||
|
12
judger.c
12
judger.c
@ -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);
|
||||
}
|
||||
|
38
runner.c
38
runner.c
@ -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
|
||||
|
7
runner.h
7
runner.h
@ -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)
|
||||
|
||||
|
||||
|
@ -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"):
|
||||
|
Loading…
Reference in New Issue
Block a user