ev_loop.rs (2276B)
1 use async_fs::File; 2 use async_signal::{Signal, Signals}; 3 use futures_lite::{AsyncReadExt, StreamExt}; 4 use log::debug; 5 use nix::errno::Errno; 6 use nix::sys::reboot::RebootMode; 7 use nix::sys::stat::Mode; 8 use nix::unistd::mkfifo; 9 10 use kanit_common::constants; 11 use kanit_common::error::{Context, Result}; 12 use kanit_executor::{block, spawn}; 13 14 use crate::{event_rc, teardown}; 15 16 async fn pipe_handler(data: Vec<u8>) -> Result<()> { 17 if data.starts_with(b"halt") { 18 teardown(Some(RebootMode::RB_HALT_SYSTEM))?; 19 } else if data.starts_with(b"poweroff") { 20 teardown(Some(RebootMode::RB_POWER_OFF))?; 21 } else if data.starts_with(b"reboot") { 22 teardown(Some(RebootMode::RB_AUTOBOOT))?; 23 } else if data.starts_with(b"kexec") { 24 teardown(Some(RebootMode::RB_KEXEC))?; 25 } else { 26 event_rc(data).await?; 27 } 28 29 Ok(()) 30 } 31 32 async fn listen_signal() -> Result<()> { 33 let mut signals = Signals::new([Signal::Int, Signal::Term, Signal::Child]) 34 .context("failed to register signals")?; 35 36 while let Some(signal) = signals.next().await { 37 let signal = if let Ok(signal) = signal { 38 signal 39 } else { 40 continue; 41 }; 42 43 debug!("*boop* {signal:?}"); 44 } 45 46 Ok(()) 47 } 48 49 async fn listen_file() -> Result<()> { 50 mkfifo(constants::KAN_PIPE, Mode::S_IRUSR | Mode::S_IWUSR).context("failed to create pipe")?; 51 52 loop { 53 let mut buff = vec![0u8; 512]; 54 55 let mut file = match File::open(constants::KAN_PIPE).await { 56 Ok(f) => f, 57 Err(e) => match e.raw_os_error() { 58 None => return Err(e.into()), 59 Some(n) => { 60 if Errno::from_raw(n) == Errno::EINTR { 61 continue; 62 } else { 63 return Err(e.into()); 64 } 65 } 66 }, 67 }; 68 69 file.read(&mut buff).await.context("failed to read pipe")?; 70 71 spawn(pipe_handler(buff)).detach(); 72 } 73 } 74 75 async fn inner_ev_loop() -> Result<()> { 76 let handles = [spawn(listen_signal()), spawn(listen_file())]; 77 78 for handle in handles { 79 handle.await?; 80 } 81 82 Ok(()) 83 } 84 85 pub fn ev_loop() -> Result<()> { 86 block(inner_ev_loop())?; 87 88 Ok(()) 89 }