1
0
Fork 0
polytree-session/src/task.rs

85 lines
1.9 KiB
Rust
Raw Normal View History

use std::ffi::CString;
2021-12-05 16:00:23 +00:00
use std::fmt::Debug;
2021-12-05 15:26:22 +00:00
2021-12-05 16:00:23 +00:00
#[derive(Clone, Debug)]
2021-12-05 15:33:48 +00:00
pub struct TaskConfig {
exe: String,
}
2021-12-05 16:00:23 +00:00
#[derive(Clone, Debug)]
2021-12-05 15:39:41 +00:00
pub struct TaskInfo {
config: TaskConfig,
pid: libc::pid_t,
}
2021-12-05 16:00:23 +00:00
#[derive(Clone, Debug)]
2021-12-05 15:26:22 +00:00
pub struct TaskResult {
2021-12-05 15:39:41 +00:00
info: TaskInfo,
2021-12-05 15:26:22 +00:00
status: i32,
}
2021-12-05 15:33:48 +00:00
impl TaskConfig {
pub fn new<Exe: Into<String>>(exe: Exe) -> Self {
Self { exe: exe.into() }
}
}
2021-12-05 15:39:41 +00:00
impl TaskInfo {
pub fn new(config: TaskConfig, pid: libc::pid_t) -> Self {
Self { config, pid }
}
}
2021-12-05 15:26:22 +00:00
impl TaskResult {
2021-12-05 15:39:41 +00:00
pub fn new(info: TaskInfo, status: i32) -> Self {
Self { info, status }
}
2021-12-05 15:26:22 +00:00
pub fn status(&self) -> i32 {
self.status
}
}
2021-12-05 16:00:23 +00:00
pub trait Task: Debug + Sized {
fn new(info: TaskInfo) -> Self;
fn info(&self) -> &TaskInfo;
fn start(config: TaskConfig) -> Result<Self, String> {
unsafe {
let pid = libc::fork();
if pid == -1 {
return Err("fork".into());
}
if pid == 0 {
2021-12-05 16:52:30 +00:00
let arg0 = CString::new(config.exe.as_bytes()).unwrap();
let args = vec![arg0.as_ptr(), std::ptr::null()];
libc::execvp(arg0.as_ptr(), args.as_ptr());
libc::exit(libc::EXIT_FAILURE);
}
Ok(Self::new(TaskInfo::new(config, pid)))
}
}
fn wait(self) -> TaskResult {
unsafe {
let status: i32 = 0;
2021-12-05 16:52:30 +00:00
libc::waitpid(self.info().pid, status as *mut i32, 0);
let status = libc::WEXITSTATUS(status);
TaskResult::new(self.info().clone(), status)
}
}
2021-12-05 16:09:52 +00:00
fn terminate(self) -> TaskResult {
unsafe {
2021-12-05 16:52:30 +00:00
libc::kill(self.info().pid, libc::SIGKILL);
2021-12-05 16:09:52 +00:00
let status: i32 = 0;
2021-12-05 16:52:30 +00:00
libc::waitpid(self.info().pid, status as *mut i32, 0);
2021-12-05 16:09:52 +00:00
let status = libc::WEXITSTATUS(status);
TaskResult::new(self.info().clone(), status)
}
}
}