mirror of
https://github.com/MeiK2333/river.git
synced 2025-09-26 22:49:11 +08:00
Update
This commit is contained in:
parent
7931f6b2bc
commit
55d090af9d
18
src/error.rs
18
src/error.rs
@ -1,5 +1,7 @@
|
||||
use crate::river::judge_response::{JudgeResult, JudgeStatus};
|
||||
use crate::river::JudgeResponse;
|
||||
use libc::strerror;
|
||||
use std::ffi::CStr;
|
||||
use std::fmt;
|
||||
use std::io;
|
||||
use std::result;
|
||||
@ -9,13 +11,29 @@ pub enum Error {
|
||||
CreateTempDirError(io::Error),
|
||||
LanguageNotFound(i32),
|
||||
FileWriteError(io::Error),
|
||||
ForkError(Option<i32>),
|
||||
}
|
||||
|
||||
pub type Result<T> = result::Result<T, Error>;
|
||||
|
||||
pub fn errno_str(errno: Option<i32>) -> String {
|
||||
match errno {
|
||||
Some(no) => {
|
||||
let stre = unsafe { strerror(no) };
|
||||
let c_str: &CStr = unsafe { CStr::from_ptr(stre) };
|
||||
c_str.to_str().unwrap().to_string()
|
||||
}
|
||||
_ => "Unknown Error!".to_string(),
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Error {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
match *self {
|
||||
Error::ForkError(errno) => {
|
||||
let reason = errno_str(errno);
|
||||
write!(f, "ForkError: {}", reason)
|
||||
}
|
||||
_ => write!(f, "{:?}", self),
|
||||
}
|
||||
}
|
||||
|
@ -31,7 +31,6 @@ pub async fn compile(request: &JudgeRequest, path: &Path) -> Result<JudgeRespons
|
||||
Some(Language::Go) => "main.go",
|
||||
None => return Err(Error::LanguageNotFound(request.language)),
|
||||
};
|
||||
|
||||
if let Err(e) = fs::write(path.join(filename), request.code.clone()).await {
|
||||
return Err(Error::FileWriteError(e));
|
||||
};
|
||||
|
@ -1,41 +1,91 @@
|
||||
use super::error::{Error, Result};
|
||||
use libc;
|
||||
use std::future::Future;
|
||||
use std::io;
|
||||
use std::pin::Pin;
|
||||
use std::task::{Context, Poll};
|
||||
use std::thread;
|
||||
use std::time::Duration;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Process {
|
||||
pub pid: i32,
|
||||
pub time_limit: i32,
|
||||
pub read_time_limit: i32,
|
||||
pub memory_limit: i32,
|
||||
pub stdin_fd: i32,
|
||||
pub stdout_fd: i32,
|
||||
pub stderr_fd: i32,
|
||||
pub cmd: str,
|
||||
pub cmd: String,
|
||||
}
|
||||
|
||||
impl Process {
|
||||
pub fn new() -> Process {
|
||||
Process {
|
||||
pid: -1,
|
||||
time_limit: -1,
|
||||
memory_limit: -1,
|
||||
stdin_fd: -1,
|
||||
stdout_fd: -1,
|
||||
stderr_fd: -1,
|
||||
cmd: "".to_string(),
|
||||
}
|
||||
}
|
||||
pub fn set_pid(&mut self, pid: i32) {
|
||||
self.pid = pid;
|
||||
}
|
||||
}
|
||||
|
||||
impl Future for Process {
|
||||
type Output = &'static str;
|
||||
type Output = Result<ProcessStatus>;
|
||||
|
||||
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<&'static str> {
|
||||
let mut status = 0;
|
||||
unsafe {
|
||||
// TODO: fork、修改用户、组、设置限制,exec 等等
|
||||
// TODO: seccomp 等保证安全
|
||||
let _pid = libc::waitpid(self.pid, &mut status, libc::WNOHANG);
|
||||
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<ProcessStatus>> {
|
||||
// pid == -1 时为第一次触发,此时开始运行
|
||||
// 直到进程执行完毕, wake 通知进入下次检查
|
||||
if self.pid == -1 {
|
||||
let pid;
|
||||
unsafe {
|
||||
pid = libc::fork();
|
||||
}
|
||||
if pid == 0 {
|
||||
// 子进程
|
||||
// TODO: fork、修改用户、组、设置限制,exec 等等
|
||||
// TODO: seccomp 等保证安全
|
||||
let process = Pin::into_inner(self).clone();
|
||||
run(process);
|
||||
} else if pid > 0 {
|
||||
// 父进程
|
||||
self.as_mut().set_pid(pid);
|
||||
let waker = cx.waker().clone();
|
||||
let pid = self.pid;
|
||||
|
||||
thread::spawn(move || {
|
||||
// 等待子进程结束
|
||||
wait(pid);
|
||||
// 触发唤醒异步
|
||||
waker.wake();
|
||||
});
|
||||
} else {
|
||||
// 出错
|
||||
return Poll::Ready(Err(Error::ForkError(
|
||||
io::Error::last_os_error().raw_os_error(),
|
||||
)));
|
||||
}
|
||||
return Poll::Pending;
|
||||
} else {
|
||||
// 子进程结束后被唤醒
|
||||
// 收集运行信息,返回数据,结束异步
|
||||
wait(self.pid);
|
||||
// TODO: Poll::Ready
|
||||
return Poll::Pending;
|
||||
}
|
||||
if status != 0 {
|
||||
return Poll::Ready("");
|
||||
}
|
||||
let waker = cx.waker().clone();
|
||||
|
||||
thread::spawn(move || {
|
||||
thread::sleep(Duration::from_millis(3000));
|
||||
waker.wake();
|
||||
});
|
||||
|
||||
Poll::Pending
|
||||
}
|
||||
}
|
||||
|
||||
fn run(process: Process) {}
|
||||
|
||||
fn wait(pid: i32) {}
|
||||
|
||||
pub struct ProcessStatus {
|
||||
pub rusage: libc::rusage,
|
||||
pub exit_code: i32,
|
||||
pub status: i32,
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user