proc_man/proc_man_rpc/src/lib.rs

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);
}
}