diff --git a/src/bin/commands/config.rs b/src/bin/commands/config.rs index c37812f..62f5f42 100644 --- a/src/bin/commands/config.rs +++ b/src/bin/commands/config.rs @@ -299,25 +299,10 @@ fn load_keymap( } }; - let mut bpf = match aya::Bpf::load(&bpf) { - Ok(bpf) => bpf, - Err(e) => { - eprintln!("error: {}: {e}", keymap_filename.display()); - std::process::exit(1); - } - }; - - let program: &mut LircMode2 = bpf - .program_mut(&keymap.name) - .expect("function missing") - .try_into() - .unwrap(); - - program.load().unwrap(); - - let link = program.attach(chdev.as_fd()).expect("attach"); - - program.take_link(link).unwrap(); + if let Err(e) = chdev.attach_bpf(&bpf) { + eprintln!("error: {}: {e}", keymap_filename.display()); + std::process::exit(1); + } } } } @@ -376,25 +361,10 @@ fn load_lircd( } }; - let mut bpf = match aya::Bpf::load(&bpf) { - Ok(bpf) => bpf, - Err(e) => { - eprintln!("error: {}: {e}", keymap_filename.display()); - std::process::exit(1); - } - }; - - let program: &mut LircMode2 = bpf - .program_mut(&remote.name) - .expect("function missing") - .try_into() - .unwrap(); - - program.load().unwrap(); - - let link = program.attach(chdev.as_fd()).expect("attach"); - - program.take_link(link).unwrap(); + if let Err(e) = chdev.attach_bpf(&bpf) { + eprintln!("error: {}: {e}", keymap_filename.display()); + std::process::exit(1); + } for code in remote.codes { let mut name = code.name.to_uppercase(); diff --git a/src/lirc.rs b/src/lirc.rs index d652ed8..59212fe 100644 --- a/src/lirc.rs +++ b/src/lirc.rs @@ -1,5 +1,6 @@ //! Interface to lirc chardevs on Linux +use aya::programs::LircMode2; use nix::{ioctl_read, ioctl_write_ptr}; use num_integer::Integer; use std::{ @@ -456,6 +457,46 @@ impl Lirc { pub fn as_file(&self) -> &File { &self.file } + + /// Load and attach bpf program. + pub fn attach_bpf(&self, bpf: &[u8]) -> Result<(), String> { + let mut bpf = match aya::Bpf::load(bpf) { + Ok(bpf) => bpf, + Err(e) => { + return Err(format!("{e}")); + } + }; + + let mut iter = bpf.programs_mut(); + + let Some((_, program)) = iter.next() else { + return Err("missing program".into()); + }; + + if iter.next().is_some() { + return Err("only single program expected".into()); + } + + let program: &mut LircMode2 = match program.try_into() { + Ok(program) => program, + Err(e) => { + return Err(format!("{e}")); + } + }; + + if let Err(e) = program.load() { + return Err(format!("{e}")); + } + + match program.attach(self.as_fd()) { + Ok(link) => { + program.take_link(link).unwrap(); + + Ok(()) + } + Err(e) => Err(format!("{e}")), + } + } } impl AsRawFd for Lirc {