mirror of
https://github.com/MeiK2333/river.git
synced 2025-11-04 14:49:40 +08:00
删除当前无用的返回结果
This commit is contained in:
parent
e56903de1c
commit
33aa793a79
@ -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;
|
||||
|
||||
@ -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,
|
||||
}
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -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)
|
||||
};
|
||||
|
||||
@ -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,
|
||||
|
||||
Loading…
Reference in New Issue
Block a user