getty.rs (1370B)
1 use std::sync::OnceLock; 2 3 use async_trait::async_trait; 4 use blocking::unblock; 5 use nix::sys::signal::{Signal, kill}; 6 use nix::unistd::Pid; 7 8 use kanit_common::error::Result; 9 use kanit_supervisor::{RestartPolicy, SupervisorBuilder}; 10 use kanit_unit::{Unit, UnitName}; 11 12 pub struct GeTTY { 13 name: String, 14 pid: u32, 15 tty: &'static str, 16 serial: bool, 17 } 18 19 impl GeTTY { 20 pub fn new(tty: &'static str, serial: bool) -> Self { 21 Self { 22 name: format!("getty@{tty}"), 23 pid: 0, 24 tty, 25 serial, 26 } 27 } 28 } 29 30 #[async_trait] 31 impl Unit for GeTTY { 32 fn name(&self) -> UnitName { 33 static NAME: OnceLock<UnitName> = OnceLock::new(); 34 35 NAME.get_or_init(|| UnitName::from(self.name.clone())) 36 .clone() 37 } 38 39 async fn start(&mut self) -> Result<()> { 40 let child = if self.serial { 41 SupervisorBuilder::new("getty", ["-L", "0", self.tty, "vt100"]) 42 } else { 43 SupervisorBuilder::new("getty", ["38400", self.tty]) 44 } 45 .restart_policy(RestartPolicy::Always) 46 .restart_delay(2) 47 .spawn()?; 48 49 self.pid = child.id(); 50 51 Ok(()) 52 } 53 54 async fn stop(&mut self) -> Result<()> { 55 let pid = self.pid; 56 let _ = unblock(move || kill(Pid::from_raw(pid as i32), Signal::SIGKILL)).await; 57 58 Ok(()) 59 } 60 }