From d3ed13ea13cce5c2b9cd5361dfc2524966a1fec3 Mon Sep 17 00:00:00 2001 From: MeiK Date: Thu, 21 May 2020 15:05:28 +0800 Subject: [PATCH] Update TODO --- README.md | 7 ++++++- src/error.rs | 2 +- src/main.rs | 1 + src/process.rs | 43 +++++++++++++++++++++++++++++++++---------- src/result.rs | 34 +++++++++++++++------------------- tests/response.json | 44 ++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 100 insertions(+), 31 deletions(-) create mode 100644 tests/response.json diff --git a/README.md b/README.md index fb53281..19de6a2 100644 --- a/README.md +++ b/README.md @@ -1 +1,6 @@ -# river \ No newline at end of file +# river + +## TODO + +- 资源限制 +- 资源占用过多的错误 diff --git a/src/error.rs b/src/error.rs index 990e9c6..2d28381 100644 --- a/src/error.rs +++ b/src/error.rs @@ -21,7 +21,7 @@ pub enum Error { TemplateRenderError(RenderError), LanguageConfigError(String), CreateTempDirError(io::Error), - CloseTempDirError(io::Error), + // CloseTempDirError(io::Error), CopyFileError(io::Error), OsStringToStringError(OsString), ForkError(Option), diff --git a/src/main.rs b/src/main.rs index 3694d55..7228ab1 100644 --- a/src/main.rs +++ b/src/main.rs @@ -36,6 +36,7 @@ fn main() { match process::run(&judge_config) { Ok(_) => {} Err(err) => { + // TODO: SE eprintln!("{}", err); return; } diff --git a/src/process.rs b/src/process.rs index 294c221..3190be6 100644 --- a/src/process.rs +++ b/src/process.rs @@ -134,11 +134,18 @@ pub fn run(judge_config: &JudgeConfig) -> Result<()> { }; } // TODO: 处理 CE 与 RE(编译期间程序运行出错为 CE,运行期间出错为 RE) - let _ = compile(judge_config, to_dir)?; + let compile_status = compile(judge_config, to_dir)?; + if !compile_status.exited { + // TODO: CE + } + for test_case in &judge_config.tests { let exit_status = run_one(judge_config, test_case, to_dir)?; let output_file_path = to_dir.join(&test_case.output_file); let answer_file_path = from_dir.join(&test_case.answer_file); + if !exit_status.exited { + // TODO: RE + } let res = TestCaseResult::standard(&output_file_path, &answer_file_path, exit_status); println!("{:?}", res); match fs::remove_file(output_file_path) { @@ -151,10 +158,11 @@ pub fn run(judge_config: &JudgeConfig) -> Result<()> { } }; } - match pwd.close() { - Ok(_) => {} - Err(err) => return Err(Error::CloseTempDirError(err)), - }; + println!("{:?}", pwd); + // match pwd.close() { + // Ok(_) => {} + // Err(err) => return Err(Error::CloseTempDirError(err)), + // }; Ok(()) } @@ -200,9 +208,26 @@ pub fn wait(pid: i32) -> Result { Ok(elapsed) => elapsed.as_millis(), Err(err) => return Err(Error::SystemTimeError(err)), }; + let signal = unsafe { + if libc::WIFSIGNALED(status) { + libc::WTERMSIG(status) + } else if libc::WIFSTOPPED(status) { + libc::WSTOPSIG(status) + } else { + 0 + } + }; + let exited = unsafe { libc::WIFEXITED(status) }; + if exited { + status = unsafe { libc::WEXITSTATUS(status) }; + } + let coredump = unsafe { libc::WCOREDUMP(status) }; Ok(ExitStatus { rusage, status, + signal, + exited, + coredump, time_used, real_time_used, memory_used, @@ -267,15 +292,14 @@ pub fn run_one( panic!("How dare you!"); } else if pid > 0 { // 父进程 - let exit_status = wait(pid)?; - return Ok(exit_status); + return Ok(wait(pid)?); } else { // 异常 return Err(Error::ForkError(io::Error::last_os_error().raw_os_error())); } } -pub fn compile(judge_config: &JudgeConfig, workdir: &Path) -> Result<()> { +pub fn compile(judge_config: &JudgeConfig, workdir: &Path) -> Result { let pid; unsafe { pid = libc::fork(); @@ -292,9 +316,8 @@ pub fn compile(judge_config: &JudgeConfig, workdir: &Path) -> Result<()> { } panic!("How dare you!"); } else if pid > 0 { - let _ = wait(pid)?; + return Ok(wait(pid)?); } else { return Err(Error::ForkError(io::Error::last_os_error().raw_os_error())); } - Ok(()) } diff --git a/src/result.rs b/src/result.rs index 2aafeb6..73ab3c0 100644 --- a/src/result.rs +++ b/src/result.rs @@ -6,15 +6,12 @@ use std::fs::File; use std::io::{self, BufRead, BufReader}; use std::path::Path; -#[derive(Debug, Copy, Clone)] -pub struct ResourceUsed { - pub time_used: i64, - pub memory_used: i64, -} - pub struct ExitStatus { pub rusage: libc::rusage, pub status: i32, + pub signal: i32, + pub exited: bool, + pub coredump: bool, pub time_used: i64, pub real_time_used: u128, pub memory_used: i64, @@ -22,11 +19,11 @@ pub struct ExitStatus { #[derive(Debug, Clone)] pub enum TestCaseResult { - Accepted(ResourceUsed), - CompileError(ResourceUsed, String), - WrongAnswer(ResourceUsed), - RuntimeError(ResourceUsed, String), - SystemError(ResourceUsed, String), + Accepted, + CompileError(String), + WrongAnswer, + RuntimeError(String), + SystemError(String), } impl fmt::Display for TestCaseResult { @@ -45,10 +42,9 @@ impl TestCaseResult { println!("time used:\t{}", exit_status.time_used); println!("real time used:\t{}", exit_status.real_time_used); println!("memory used:\t{}", exit_status.rusage.ru_maxrss); - let used = ResourceUsed { - time_used: exit_status.time_used, - memory_used: exit_status.rusage.ru_maxrss, - }; + println!("status:\t{}", exit_status.status); + println!("signal:\t{}", exit_status.signal); + println!("exited:\t{}", exit_status.exited); let output_filename = match output_file.as_ref().to_str() { Some(val) => val, @@ -108,13 +104,13 @@ impl TestCaseResult { break; } if output_buffer.trim_end() != answer_buffer.trim_end() { - return Ok(TestCaseResult::WrongAnswer(used)); + return Ok(TestCaseResult::WrongAnswer); } } // 末尾的空白字符不影响结果 while output_bytes != 0 { if output_buffer.trim() != "" { - return Ok(TestCaseResult::WrongAnswer(used)); + return Ok(TestCaseResult::WrongAnswer); } output_bytes = match output_reader.read_line(&mut output_buffer) { Ok(val) => val, @@ -128,7 +124,7 @@ impl TestCaseResult { } while answer_bytes != 0 { if answer_buffer.trim() != "" { - return Ok(TestCaseResult::WrongAnswer(used)); + return Ok(TestCaseResult::WrongAnswer); } answer_bytes = match answer_reader.read_line(&mut answer_buffer) { Ok(val) => val, @@ -141,6 +137,6 @@ impl TestCaseResult { }; } - Ok(TestCaseResult::Accepted(used)) + Ok(TestCaseResult::Accepted) } } diff --git a/tests/response.json b/tests/response.json new file mode 100644 index 0000000..7346996 --- /dev/null +++ b/tests/response.json @@ -0,0 +1,44 @@ +{ + "compile": { + "time": 120, + "memory": 4096, + "status": 0, + "signal": 0, + "exited": true, + "output": "main.c: In function ‘main’: \nmain.c:5:5: warning: ignoring return value of ‘scanf’, declared with attribute warn_unused_result [-Wunused-result] \n scanf(\"%d %d\", &a, &b);" + }, + "tests": [ + { + "time": 0, + "memory": 1576, + "status": 0, + "signal": 0, + "exited": true, + "result": "Accepted" + }, + { + "time": 0, + "memory": 1576, + "status": 0, + "signal": 0, + "exited": true, + "result": "WrongAnswer" + }, + { + "time": 0, + "memory": 1576, + "status": 0, + "signal": 0, + "exited": true, + "result": "Accepted" + }, + { + "time": 0, + "memory": 1576, + "status": 139, + "signal": 11, + "exited": false, + "result": "RuntimeError" + } + ] +} \ No newline at end of file