删除当前无用的返回结果

This commit is contained in:
MeiK 2020-09-03 15:45:27 +08:00
parent e56903de1c
commit 33aa793a79
5 changed files with 72 additions and 51 deletions

View File

@ -47,10 +47,10 @@ message JudgeResponse {
SystemError = 8;
}
JudgeResult result = 3;
int32 errno = 4;
int32 exit_code = 5;
string stdout = 6;
string stderr = 7;
// int32 errno = 4;
// int32 exit_code = 5;
// string stdout = 6;
// string stderr = 7;
string errmsg = 8;
enum JudgeStatus {
Pending = 0;

View File

@ -4,6 +4,7 @@ use libc::strerror;
use std::ffi::{CStr, NulError, OsString};
use std::fmt;
use std::io;
use std::path::PathBuf;
use std::result;
#[derive(Debug)]
@ -14,6 +15,7 @@ pub enum Error {
ChannelRecvError,
StringToCStringError(NulError),
OsStringToStringError(OsString),
RemoveFileError(PathBuf),
}
pub type Result<T> = result::Result<T, Error>;
@ -42,10 +44,6 @@ pub fn system_error(err: Error) -> JudgeResponse {
time_used: 0,
memory_used: 0,
result: JudgeResult::SystemError as i32,
errno: 0,
exit_code: 0,
stdout: "".into(),
stderr: "".into(),
errmsg: format!("{}", err).into(),
status: JudgeStatus::Ended as i32,
}

View File

@ -12,10 +12,6 @@ impl JudgeResponse {
time_used: 0,
memory_used: 0,
result: JudgeResult::Accepted as i32,
errno: 0,
exit_code: 0,
stdout: "".into(),
stderr: "".into(),
errmsg: "".into(),
status: JudgeStatus::Running as i32,
}
@ -24,19 +20,48 @@ impl JudgeResponse {
fn set_process_status(self: &mut Self, status: &ProcessStatus) {
self.time_used = status.time_used;
self.memory_used = status.memory_used;
self.exit_code = status.exit_code;
self.errno = status.signal;
self.stdout = status.stdout.clone();
self.stderr = status.stderr.clone();
}
}
pub async fn judger(request: &JudgeRequest) -> Result<JudgeResponse> {
// TODO
pub async fn judger(request: &JudgeRequest, path: &Path) -> Result<JudgeResponse> {
let mut resp = JudgeResponse::new();
resp.time_used = request.time_limit.into();
let cmd = match Language::from_i32(request.language) {
Some(Language::C) => "./a.out",
Some(Language::Cpp) => "./a.out",
Some(Language::Python) => "/usr/bin/python3 main.py",
Some(Language::Rust) => "./a.out",
Some(Language::Node) => "node main.js",
Some(Language::TypeScript) => "node main.js",
Some(Language::Go) => "./a.out",
None => return Err(Error::LanguageNotFound(request.language)),
};
let mut process = Process::new();
process.cmd = cmd.to_string();
process.workdir = path.to_path_buf();
process.time_limit = request.time_limit;
process.memory_limit = request.memory_limit;
// 写入输入文件
let in_file = path.join("stdin.txt");
if let Err(e) = fs::write(in_file.clone(), request.in_data.clone()).await {
return Err(Error::FileWriteError(e));
};
process.stdin_file = Some(in_file.clone());
let status = process.await?;
if let Err(_) = fs::remove_file(in_file.clone()).await {
return Err(Error::RemoveFileError(in_file.clone()));
}
resp.status = JudgeStatus::Ended as i32;
return Ok(resp);
// TODO: 对比答案,检查结果
if status.exit_code != 0 {
resp.set_process_status(&status);
resp.result = JudgeResult::CompileError as i32;
resp.status = JudgeStatus::Ended as i32;
}
Ok(resp)
}
pub async fn compile(request: &JudgeRequest, path: &Path) -> Result<JudgeResponse> {
@ -58,31 +83,30 @@ pub async fn compile(request: &JudgeRequest, path: &Path) -> Result<JudgeRespons
let mut process = Process::new();
let cmd = match Language::from_i32(request.language) {
Some(Language::C) => "gcc main.c",
Some(Language::Cpp) => "g++ main.cpp",
Some(Language::C) => "/usr/bin/gcc main.c -o a.out -Wall -O2 -std=c99 --static",
Some(Language::Cpp) => "/usr/bin/g++ main.cpp -O2 -Wall --static -o a.out --std=gnu++17",
Some(Language::Python) => "/usr/bin/python3 -m compileall main.py",
Some(Language::Rust) => "rustc main.rs",
Some(Language::Rust) => "/usr/bin/rustc main.rs -o a.out -C opt-level=2",
// 无需编译的语言直接返回
// TODO: eslint......
Some(Language::Node) => return Ok(resp),
Some(Language::TypeScript) => "tsc",
Some(Language::Go) => "main.go",
Some(Language::TypeScript) => "/usr/bin/tsc",
Some(Language::Go) => "/usr/bin/go build -ldflags \"-s -w\" main.go",
None => return Err(Error::LanguageNotFound(request.language)),
};
process.cmd = cmd.to_string();
process.workdir = path.to_path_buf();
process.time_limit = request.time_limit;
process.memory_limit = request.memory_limit;
process.stdout_file = Some("stdout.txt".to_string());
process.stderr_file = Some("stderr.txt".to_string());
let status = process.await?;
if status.exit_code != 0 {
resp.set_process_status(&status);
resp.errmsg = status.stdout;
resp.result = JudgeResult::CompileError as i32;
resp.status = JudgeStatus::Ended as i32;
}
return Ok(resp);
Ok(resp)
}
pub fn pending() -> JudgeResponse {

View File

@ -66,7 +66,7 @@ impl River for RiverService {
need_compile = false;
yield judger::running();
let result = match judger::judger(&req).await {
let result = match judger::judger(&req, &pwd.path()).await {
Ok(res) => res,
Err(e) => error::system_error(e)
};

View File

@ -21,9 +21,7 @@ pub struct Process {
pub workdir: PathBuf,
pub time_limit: i32,
pub memory_limit: i32,
pub stdin_file: Option<String>,
pub stdout_file: Option<String>,
pub stderr_file: Option<String>,
pub stdin_file: Option<PathBuf>,
pub cmd: String,
tx: Arc<Mutex<mpsc::Sender<ProcessStatus>>>,
rx: Arc<Mutex<mpsc::Receiver<ProcessStatus>>>,
@ -37,8 +35,6 @@ impl Process {
time_limit: -1,
memory_limit: -1,
stdin_file: None,
stdout_file: None,
stderr_file: None,
cmd: "".to_string(),
workdir: PathBuf::from(""),
tx: Arc::new(Mutex::new(tx)),
@ -185,24 +181,21 @@ fn run(process: Process) {
// TODO: 资源限制等
// 重定向文件描述符
if let Some(file) = process.stdin_file {
dup(&file, libc::STDIN_FILENO, libc::O_RDONLY, 0o644)
}
if let Some(file) = process.stdout_file {
dup(
&file,
libc::STDOUT_FILENO,
libc::O_CREAT | libc::O_RDWR,
0o644,
)
}
if let Some(file) = process.stderr_file {
dup(
&file,
libc::STDERR_FILENO,
libc::O_CREAT | libc::O_RDWR,
0o644,
)
let filename = file.to_str().unwrap();
dup(&filename, libc::STDIN_FILENO, libc::O_RDONLY, 0o644)
}
dup(
"stdout.txt",
libc::STDOUT_FILENO,
libc::O_CREAT | libc::O_RDWR,
0o644,
);
dup(
"stderr.txt",
libc::STDERR_FILENO,
libc::O_CREAT | libc::O_RDWR,
0o644,
);
libc::execve(exec_args.pathname, exec_args.argv, exec_args.envp);
}
panic!("How dare you!");
@ -290,10 +283,16 @@ fn wait(pid: i32, workdir: PathBuf) -> ProcessStatus {
Ok(val) => val,
Err(_) => panic!("How dare you!"),
};
if let Err(_) = fs::remove_file(workdir.join("stdout.txt")) {
panic!("How dare you!");
}
let stderr = match fs::read_to_string(workdir.join("stderr.txt")) {
Ok(val) => val,
Err(_) => panic!("How dare you!"),
};
if let Err(_) = fs::remove_file(workdir.join("stderr.txt")) {
panic!("How dare you!");
}
return ProcessStatus {
rusage: rusage,
exit_code: exit_code,