重构部分代码结构

This commit is contained in:
MeiK 2020-09-08 18:39:30 +08:00
parent a4fa159370
commit 5a45a33eb7

View File

@ -96,7 +96,7 @@ impl Future for Process {
// 如果 pid == -1则说明子进程还没有运行开始进程
if process.pid == -1 {
let (tx, rx) = mpsc::channel();
let process_clone = process.clone();
let mut process_clone = process.clone();
let waker = cx.waker().clone();
thread::spawn(move || {
let pid;
@ -104,10 +104,11 @@ impl Future for Process {
pid = libc::fork();
}
if pid == 0 {
run(process_clone);
process_clone.run();
} else if pid > 0 {
tx.send(pid).unwrap();
let status = wait(pid, &process_clone.workdir);
process_clone.set_pid(pid);
let status = process_clone.wait();
let status_tx = process_clone.tx.lock().unwrap();
status_tx.send(status).unwrap();
waker.wake();
@ -228,11 +229,12 @@ extern "C" {
) -> libc::c_int;
}
fn run(process: Process) {
impl Process {
fn run(&self) {
// 子进程里崩溃也无法返回,崩溃就直接崩溃了
let exec_args = ExecArgs::build(&process.cmd).unwrap();
let exec_args = ExecArgs::build(&self.cmd).unwrap();
// 修改工作目录
env::set_current_dir(&process.workdir).unwrap();
env::set_current_dir(&self.workdir).unwrap();
let mut rl = libc::rlimit {
rlim_cur: 0,
rlim_max: 0,
@ -244,13 +246,13 @@ fn run(process: Process) {
tv_usec: 0,
},
it_value: libc::timeval {
tv_sec: i64::from(process.time_limit / 1000 + 2) * 2,
tv_sec: i64::from(self.time_limit / 1000 + 2) * 2,
tv_usec: 0,
},
};
unsafe {
// 重定向文件描述符
if let Some(file) = &process.stdin_file {
if let Some(file) = &self.stdin_file {
let filename = file.to_str().unwrap();
dup(&filename, libc::STDIN_FILENO, libc::O_RDONLY, 0o644)
}
@ -273,7 +275,7 @@ fn run(process: Process) {
panic!("How dare you!");
}
// CPU 时间限制,粒度为 S
rl.rlim_cur = (process.time_limit / 1000 + 1) as u64;
rl.rlim_cur = (self.time_limit / 1000 + 1) as u64;
rl.rlim_max = rl.rlim_cur + 1;
if libc::setrlimit(libc::RLIMIT_CPU, &rl) != 0 {
eprintln!("setrlimit failure!");
@ -281,7 +283,7 @@ fn run(process: Process) {
panic!("How dare you!");
}
// 设置内存限制
rl.rlim_cur = (process.memory_limit * 1024) as u64;
rl.rlim_cur = (self.memory_limit * 1024) as u64;
rl.rlim_max = rl.rlim_cur + 1024;
if libc::setrlimit(libc::RLIMIT_DATA, &rl) != 0 {
eprintln!("setrlimit failure!");
@ -297,6 +299,7 @@ fn run(process: Process) {
}
panic!("How dare you!");
}
}
unsafe fn dup(filename: &str, to: libc::c_int, flag: libc::c_int, mode: libc::c_int) {
let filename_str = CString::new(filename).unwrap();
@ -316,7 +319,9 @@ unsafe fn dup(filename: &str, to: libc::c_int, flag: libc::c_int, mode: libc::c_
}
}
fn wait(pid: i32, workdir: &PathBuf) -> ProcessStatus {
impl Process {
fn wait(&self) -> ProcessStatus {
let pid = self.pid;
let start = SystemTime::now();
let mut status = 0;
let mut rusage = libc::rusage {
@ -378,18 +383,18 @@ fn wait(pid: i32, workdir: &PathBuf) -> ProcessStatus {
// How dare you!
Err(_) => panic!("How dare you!"),
};
let stdout = match fs::read_to_string(workdir.join("stdout.txt")) {
let stdout = match fs::read_to_string(&self.workdir.join("stdout.txt")) {
Ok(val) => val,
Err(_) => panic!("How dare you!"),
};
if let Err(_) = fs::remove_file(workdir.join("stdout.txt")) {
if let Err(_) = fs::remove_file(&self.workdir.join("stdout.txt")) {
panic!("How dare you!");
}
let stderr = match fs::read_to_string(workdir.join("stderr.txt")) {
let stderr = match fs::read_to_string(&self.workdir.join("stderr.txt")) {
Ok(val) => val,
Err(_) => panic!("How dare you!"),
};
if let Err(_) = fs::remove_file(workdir.join("stderr.txt")) {
if let Err(_) = fs::remove_file(&self.workdir.join("stderr.txt")) {
panic!("How dare you!");
}
return ProcessStatus {
@ -404,6 +409,7 @@ fn wait(pid: i32, workdir: &PathBuf) -> ProcessStatus {
stderr: stderr,
};
}
}
#[derive(Clone)]
pub struct ProcessStatus {