okey/cli/commands/
start.rs1use std::{fs::File, io, os::fd::AsRawFd, process, thread};
2
3use anyhow::{anyhow, Result};
4use nix::unistd::{self, ForkResult};
5
6use crate::{
7 core::{InputProxy, KeyAdapter},
8 fs::{config::read_config, device::find_device_by_name},
9};
10
11pub fn start(config_path: Option<String>) -> Result<()> {
12 let parsed = read_config(config_path)?;
13
14 let handles = parsed.keyboards.into_iter().map(|keyboard| {
15 let defaults = parsed.defaults.clone();
16
17 thread::spawn(move || -> Result<()> {
18 let mut device = find_device_by_name(&keyboard.name)?
19 .ok_or(anyhow!("Device not found: {}", keyboard.name))?;
20
21 let mut proxy = InputProxy::try_from_device(&device)?;
22 let mut adapter = KeyAdapter::new(keyboard, defaults, &mut proxy);
23
24 adapter.hook(&mut device)
25 })
26 });
27
28 simple_logger::init()?;
29
30 for handle in handles {
31 handle.join().unwrap()?
32 }
33
34 Ok(())
35}
36
37pub fn start_daemon(config_path: Option<String>) -> Result<()> {
38 match unsafe { unistd::fork() } {
39 Ok(ForkResult::Parent { child, .. }) => {
40 println!("okey daemon started in the background... (PID: {})", child);
41 process::exit(0);
42 }
43 Ok(ForkResult::Child) => {
44 unistd::setsid()?;
45 unistd::chdir("/")?;
46
47 let dev_null = File::open("/dev/null")?;
48 let dev_null_fd = dev_null.as_raw_fd();
49
50 unistd::dup2(dev_null_fd, io::stdin().as_raw_fd())?;
51 unistd::dup2(dev_null_fd, io::stdout().as_raw_fd())?;
52 unistd::dup2(dev_null_fd, io::stderr().as_raw_fd())?;
53
54 start(config_path)?;
55 }
56 Err(err) => Err(err)?,
57 }
58
59 Ok(())
60}