123 lines
4.1 KiB
Rust
123 lines
4.1 KiB
Rust
#![allow(clippy::result_unit_err)]
|
|
|
|
use std::os::mikros::{
|
|
ipc::rpc::{self, IncomingCall},
|
|
Errno,
|
|
};
|
|
|
|
pub use proc_man_structs::WaitResult;
|
|
|
|
use parking_lot::RwLock;
|
|
|
|
static SERVER: RwLock<Option<Box<dyn Server>>> = RwLock::new(None);
|
|
|
|
const PROTO: u16 = 8;
|
|
|
|
pub trait Server: Send + Sync {
|
|
fn new_proc(&self, pid: u64, parent: Option<u64>) -> Result<(), Errno>;
|
|
fn set_stdio(&self, pid: u64, stdio: [Option<(u64, u64)>; 3]) -> Result<(), Errno>;
|
|
fn get_stdio(&self, from: u64) -> [Option<(u64, u64)>; 3];
|
|
fn set_cli_args(&self, pid: u64, args: Vec<String>) -> Result<(), Errno>;
|
|
fn get_cli_args(&self, from: u64) -> Vec<String>;
|
|
fn exit(&self, from: u64, code: u8);
|
|
fn wait(&self, from: u64, pid: u64, block: bool) -> Result<WaitResult, Errno>;
|
|
}
|
|
|
|
#[derive(Copy, Clone)]
|
|
pub struct Client(u64);
|
|
|
|
impl Client {
|
|
pub fn new(pid: u64) -> Self {
|
|
Self(pid)
|
|
}
|
|
|
|
pub fn new_proc(&self, pid: u64, parent: Option<u64>) -> Result<(), Errno> {
|
|
postcard::from_bytes(
|
|
&rpc::send_call(self.0, PROTO, 7, &postcard::to_stdvec(&(pid, parent)).unwrap()).get_return(),
|
|
)
|
|
.unwrap()
|
|
}
|
|
|
|
pub fn set_stdio(&self, pid: u64, stdio: [Option<(u64, u64)>; 3]) -> Result<(), Errno> {
|
|
postcard::from_bytes(
|
|
&rpc::send_call(self.0, PROTO, 0, &postcard::to_stdvec(&(pid, stdio)).unwrap()).get_return(),
|
|
)
|
|
.unwrap()
|
|
}
|
|
|
|
pub fn get_stdio(&self) -> [Option<(u64, u64)>; 3] {
|
|
postcard::from_bytes(
|
|
&rpc::send_call(self.0, PROTO, 1, &[]).get_return(),
|
|
)
|
|
.unwrap()
|
|
}
|
|
|
|
pub fn set_cli_args(&self, pid: u64, args: Vec<String>) -> Result<(), Errno> {
|
|
postcard::from_bytes(
|
|
&rpc::send_call(self.0, PROTO, 2, &postcard::to_stdvec(&(pid, args)).unwrap()).get_return(),
|
|
)
|
|
.unwrap()
|
|
}
|
|
|
|
pub fn get_cli_args(&self) -> Vec<String> {
|
|
postcard::from_bytes(
|
|
&rpc::send_call(self.0, PROTO, 3, &[]).get_return(),
|
|
)
|
|
.unwrap()
|
|
}
|
|
|
|
pub fn wait(&self, pid: u64, block: bool) -> Result<WaitResult, Errno> {
|
|
postcard::from_bytes(
|
|
&rpc::send_call(self.0, PROTO, 5, &postcard::to_stdvec(&(pid, block)).unwrap()).get_return(),
|
|
)
|
|
.unwrap()
|
|
}
|
|
}
|
|
|
|
pub fn register_server(server: Box<dyn Server>) {
|
|
*SERVER.write() = Some(server);
|
|
rpc::register_callback(PROTO, callback);
|
|
}
|
|
|
|
pub fn unregister_server() {
|
|
rpc::unregister_callback(PROTO);
|
|
*SERVER.write() = None;
|
|
}
|
|
|
|
fn callback(call: IncomingCall) {
|
|
let server_lock = SERVER.read();
|
|
let server = server_lock.as_ref().unwrap();
|
|
if call.func == 0 {
|
|
let (pid, stdio )= postcard::from_bytes(call.args()).unwrap();
|
|
let ret = postcard::to_stdvec(&server.set_stdio(pid, stdio)).unwrap();
|
|
call.send_return(&ret);
|
|
} else if call.func == 1 {
|
|
let ret = postcard::to_stdvec(&server.get_stdio(call.from)).unwrap();
|
|
call.send_return(&ret);
|
|
} else if call.func == 2 {
|
|
let (pid, args )= postcard::from_bytes(call.args()).unwrap();
|
|
let ret = postcard::to_stdvec(&server.set_cli_args(pid, args)).unwrap();
|
|
call.send_return(&ret);
|
|
} else if call.func == 3 {
|
|
let ret = postcard::to_stdvec(&server.get_cli_args(call.from)).unwrap();
|
|
call.send_return(&ret);
|
|
} else if call.func == 4 {
|
|
let (pid, code) = postcard::from_bytes(call.args()).unwrap();
|
|
let _ = server.exit(pid, code);
|
|
//call.send_return(&ret);
|
|
} else if call.func == 5 {
|
|
let (pid, block) = postcard::from_bytes(call.args()).unwrap();
|
|
let ret = postcard::to_stdvec(&server.wait(call.from, pid, block)).unwrap();
|
|
call.send_return(&ret);
|
|
} else if call.func == 6 {
|
|
let (pid, parent) = postcard::from_bytes(call.args()).unwrap();
|
|
let _ = server.new_proc(pid, parent);
|
|
//let ret = postcard::to_stdvec(&server.new_proc(pid, parent)).unwrap();
|
|
//call.send_return(&ret);
|
|
} else if call.func == 7 {
|
|
let (pid, parent) = postcard::from_bytes(call.args()).unwrap();
|
|
let ret = postcard::to_stdvec(&server.new_proc(pid, parent)).unwrap();
|
|
call.send_return(&ret);
|
|
}
|
|
}
|