cargo fmt

This commit is contained in:
Johannes Leupolz 2025-12-17 21:51:24 +00:00
parent 01417e6934
commit 045807e848
10 changed files with 118 additions and 105 deletions

View file

@ -3,7 +3,7 @@
// Author: Johannes Leupolz <dev@leupolz.eu>
use core::panic;
use std::{time::Duration};
use std::time::Duration;
use vuinputd_tests::bwrap::SandboxChildIpc;
@ -21,7 +21,7 @@ fn main() {
ipc.send(b"ok").unwrap();
} else {
ipc.send(b"nok").unwrap();
println!("child received {}",incoming_str);
println!("child received {}", incoming_str);
panic!("expected ipc message to be 'continue'");
}
}

View file

@ -3,9 +3,8 @@
// Author: Johannes Leupolz <dev@leupolz.eu>
use clap::Parser;
use libc::{CLOCK_MONOTONIC, input_event, timespec, uinput_setup};
use libc::{c_int, close, open, write, O_NONBLOCK, O_WRONLY};
use vuinputd_tests::test_log::{LoggedInputEvent, TestLog};
use libc::{input_event, timespec, uinput_setup, CLOCK_MONOTONIC};
use std::ffi::{CStr, CString};
use std::fs::{self, File, OpenOptions};
use std::io::{self, ErrorKind};
@ -14,6 +13,7 @@ use std::os::fd::AsRawFd;
use std::os::raw::{c_char, c_void};
use std::ptr;
pub use uinput_ioctls::*;
use vuinputd_tests::test_log::{LoggedInputEvent, TestLog};
// Constants (same numeric values as in linux headers)
const EV_SYN: u16 = 0x00;
@ -276,7 +276,6 @@ unsafe fn set_standard_keyboard_keys(fd: i32) -> Result<(), std::io::Error> {
Ok(())
}
#[derive(Debug, Parser)]
#[command(author, version, about)]
struct Args {
@ -322,17 +321,25 @@ fn emit(fd: c_int, ev_type: u16, code: u16, val: i32) -> io::Result<()> {
Ok(())
}
// Note that before we can read, a SYN needs to be sent. Thus combine it.
fn emit_read_and_log(emit_to: c_int, read_from:&File, ev_type: u16, code: u16, val: i32) -> io::Result<LoggedInputEvent> {
let (time_sent_sec,time_sent_nsec) = monotonic_time();
fn emit_read_and_log(
emit_to: c_int,
read_from: &File,
ev_type: u16,
code: u16,
val: i32,
) -> io::Result<LoggedInputEvent> {
let (time_sent_sec, time_sent_nsec) = monotonic_time();
emit(emit_to, ev_type, code, val)?;
emit(emit_to,EV_SYN, SYN_REPORT, 0)?;
let input_event_recv=read_event(&read_from).unwrap();
let _syn_recv=read_event(&read_from).unwrap();
let (time_recv_sec,time_recv_nsec) = monotonic_time();
let duration_nsec =(time_recv_sec-time_sent_sec)*1_000_000+(time_recv_nsec-time_sent_nsec)/1000;
let send_and_receive_match = input_event_recv.type_==ev_type && input_event_recv.code==code && input_event_recv.value==val;
emit(emit_to, EV_SYN, SYN_REPORT, 0)?;
let input_event_recv = read_event(&read_from).unwrap();
let _syn_recv = read_event(&read_from).unwrap();
let (time_recv_sec, time_recv_nsec) = monotonic_time();
let duration_nsec =
(time_recv_sec - time_sent_sec) * 1_000_000 + (time_recv_nsec - time_sent_nsec) / 1000;
let send_and_receive_match = input_event_recv.type_ == ev_type
&& input_event_recv.code == code
&& input_event_recv.value == val;
Ok(LoggedInputEvent {
tv_sec: time_sent_sec,
@ -341,13 +348,12 @@ fn emit_read_and_log(emit_to: c_int, read_from:&File, ev_type: u16, code: u16, v
type_: ev_type,
code: code,
value: val,
send_and_receive_match: send_and_receive_match
send_and_receive_match: send_and_receive_match,
})
}
pub fn fetch_device_node(path: &str) -> io::Result<String> {
println!("Read dir {}",&path);
println!("Read dir {}", &path);
for entry in fs::read_dir(path)? {
let entry = entry?; // propagate per-entry errors
if let Some(name) = entry.file_name().to_str() {
@ -360,23 +366,22 @@ pub fn fetch_device_node(path: &str) -> io::Result<String> {
Err(io::Error::new(ErrorKind::NotFound, "no device found"))
}
pub fn read_event(event_dev : &File) -> io::Result<input_event> {
pub fn read_event(event_dev: &File) -> io::Result<input_event> {
let mut ev: input_event = unsafe { mem::zeroed() };
let ret = unsafe {
libc::read(
event_dev.as_raw_fd(),
&mut ev as *mut _ as *mut c_void,
mem::size_of::<input_event>(),
)
};
libc::read(
event_dev.as_raw_fd(),
&mut ev as *mut _ as *mut c_void,
mem::size_of::<input_event>(),
)
};
if ret as usize != mem::size_of::<input_event>() {
return Err(io::Error::last_os_error());
}
Ok(ev)
}
fn monotonic_time() -> (i64,i64) {
fn monotonic_time() -> (i64, i64) {
let mut ts = timespec {
tv_sec: 0,
tv_nsec: 0,
@ -385,13 +390,12 @@ fn monotonic_time() -> (i64,i64) {
unsafe {
libc::clock_gettime(CLOCK_MONOTONIC, &mut ts);
}
(ts.tv_sec ,ts.tv_nsec)
(ts.tv_sec, ts.tv_nsec)
}
fn main() -> io::Result<()> {
// open device - matches: open("/dev/uinput", O_WRONLY | O_NONBLOCK);
let args=Args::parse();
let args = Args::parse();
let device = match args.dev_path {
Some(dev_path) => dev_path,
@ -468,7 +472,8 @@ fn main() -> io::Result<()> {
CStr::from_ptr(resultbuf.as_ptr()).to_string_lossy()
);
println!("syspath: {}", sysname);
let devnode = fetch_device_node(&sysname).unwrap_or_else(|e| panic!("failed to fetch device node!: {e}"));
let devnode = fetch_device_node(&sysname)
.unwrap_or_else(|e| panic!("failed to fetch device node!: {e}"));
println!("devnode: {}", devnode);
eprintln!("sysname: {}", sysname);
@ -477,17 +482,21 @@ fn main() -> io::Result<()> {
// Comment this out: sleep(Duration::from_secs(12));
let event_device = OpenOptions::new()
.read(true)
.open(&devnode)
.unwrap_or_else(|err| panic!("Could not open event device {}, Error {}",&devnode,err));
.read(true)
.open(&devnode)
.unwrap_or_else(|err| {
panic!("Could not open event device {}, Error {}", &devnode, err)
});
// Emit (press + syn) + (release + syn)
let ev1 = emit_read_and_log(fd, &event_device, EV_KEY, KEY_SPACE, 1)?;
let ev2 = emit_read_and_log(fd, &event_device,EV_KEY, KEY_SPACE, 0)?;
let ev2 = emit_read_and_log(fd, &event_device, EV_KEY, KEY_SPACE, 0)?;
let eventlog = TestLog{events:vec![ev1,ev2]};
let eventlog = TestLog {
events: vec![ev1, ev2],
};
let serialized = serde_json::to_string(&eventlog).unwrap();
println!("Event log: {}",serialized);
println!("Event log: {}", serialized);
// Destroy device and close fd
ui_dev_destroy(fd).unwrap_or_else(|e| {

View file

@ -119,7 +119,8 @@ impl BwrapBuilder {
}
pub fn dev_bind(mut self, src: &str, dst: &str) -> Self {
self.args.extend(["--dev-bind".into(), src.into(), dst.into()]);
self.args
.extend(["--dev-bind".into(), src.into(), dst.into()]);
self
}
@ -164,7 +165,6 @@ impl BwrapBuilder {
let mut cmd = Command::new("bwrap");
if let Some(fd) = self.ipc_child_fd.take() {
// give up ownership of ipc_child_fd in host process.
let fd = fd.into_raw_fd();
@ -204,7 +204,7 @@ mod tests {
.ro_bind("/", "/")
.tmpfs("/tmp")
.die_with_parent()
.command("/usr/bin/echo",&[])
.command("/usr/bin/echo", &[])
.run()
.unwrap_or_else(|e| panic!("failed to run bwrap!: {e}"));

View file

@ -2,13 +2,12 @@
//
// Author: Johannes Leupolz <dev@leupolz.eu>
use serde::{Serialize, Deserialize};
use serde::{Deserialize, Serialize};
#[derive(Serialize, Deserialize, Debug)]
pub struct LoggedInputEvent {
pub tv_sec: i64,
pub tv_usec: i64,
pub duration_nsec: i64,
@ -24,5 +23,5 @@ pub struct LoggedInputEvent {
#[derive(Serialize, Deserialize, Debug)]
pub struct TestLog {
pub events:Vec<LoggedInputEvent>
}
pub events: Vec<LoggedInputEvent>,
}

View file

@ -14,7 +14,7 @@ fn test_bwrap_simple() {
.ro_bind("/", "/")
.tmpfs("/tmp")
.die_with_parent()
.command("/usr/bin/echo",&["test","test","test"])
.command("/usr/bin/echo", &["test", "test", "test"])
.run()
.unwrap_or_else(|e| panic!("failed to run bwrap!: {e}"));
@ -37,12 +37,12 @@ fn test_bwrap_ipc() {
.expect("failed to create IPC");
// Note that builder.run() will block. Thus, the send needs to happen before the child process blocks
// the host process.
// the host process.
ipc.send("continue".as_bytes())
.unwrap_or_else(|e| panic!("failed to send data via ipc: {e}"));
let out = builder
.command(bwrap_ipc,&[])
.command(bwrap_ipc, &[])
.run()
.unwrap_or_else(|e| panic!("failed to run bwrap!: {e}"));
@ -54,12 +54,10 @@ fn test_bwrap_ipc() {
let result = result.expect("error receiving input from ipc as host within 5 seconds");
let result_str =
str::from_utf8(&result).expect("message received from ipc is not encoded as utf8");
println!("host received {}",result_str);
str::from_utf8(&result).expect("message received from ipc is not encoded as utf8");
println!("host received {}", result_str);
}
#[cfg(all(feature = "requires-privileges", feature = "requires-bwrap"))]
#[test]
fn test_list_sys_in_container() {
@ -68,7 +66,10 @@ fn test_list_sys_in_container() {
.ro_bind("/", "/")
.tmpfs("/tmp")
.die_with_parent()
.command("/usr/bin/ls",&["-lh","/sys/devices/virtual/input/input235"])
.command(
"/usr/bin/ls",
&["-lh", "/sys/devices/virtual/input/input235"],
)
.run()
.unwrap_or_else(|e| panic!("failed to run bwrap!: {e}"));
@ -89,12 +90,15 @@ fn test_keyboard_on_host() {
assert!(status.success());
}
#[cfg(all(feature = "requires-privileges", feature = "requires-uinput", feature = "requires-bwrap"))]
#[cfg(all(
feature = "requires-privileges",
feature = "requires-uinput",
feature = "requires-bwrap"
))]
#[test]
fn test_keyboard_in_container_with_uinput() {
let test_keyboard = env!("CARGO_BIN_EXE_test-keyboard");
let out = bwrap::BwrapBuilder::new()
.unshare_net()
.ro_bind("/", "/")
@ -102,7 +106,7 @@ fn test_keyboard_in_container_with_uinput() {
.dev_bind("/dev/uinput", "/dev/uinput")
.dev_bind("/dev/input", "/dev/input")
.die_with_parent()
.command(test_keyboard,&[])
.command(test_keyboard, &[])
.run()
.unwrap_or_else(|e| panic!("failed to run bwrap!: {e}"));
@ -113,14 +117,18 @@ fn test_keyboard_in_container_with_uinput() {
assert!(out.status.success());
}
#[cfg(all(feature = "requires-privileges", feature = "requires-uinput", feature = "requires-bwrap"))]
#[ignore]
#[cfg(all(
feature = "requires-privileges",
feature = "requires-uinput",
feature = "requires-bwrap"
))]
//#[ignore]
#[test]
fn test_keyboard_in_container_with_vuinput() {
run_vuinputd::ensure_vuinputd_running();
let test_keyboard = env!("CARGO_BIN_EXE_test-keyboard");
let out = bwrap::BwrapBuilder::new()
.unshare_net()
.ro_bind("/", "/")
@ -132,7 +140,7 @@ fn test_keyboard_in_container_with_vuinput() {
.tmpfs("/run")
.dev_bind("/dev/vuinput-test", "/dev/uinput")
.die_with_parent()
.command(test_keyboard,&[])
.command(test_keyboard, &[])
.run()
.unwrap_or_else(|e| panic!("failed to run bwrap!: {e}"));

View file

@ -2,9 +2,9 @@
//
// Author: Johannes Leupolz <dev@leupolz.eu>
use serde::{Serialize, Deserialize};
use serde::{Deserialize, Serialize};
#[derive(Serialize,Deserialize)]
#[derive(Serialize, Deserialize)]
#[serde(tag = "action")]
pub enum Action {
#[serde(rename = "mknod-device")]
@ -16,12 +16,8 @@ pub enum Action {
},
#[serde(rename = "announce-via-netlink")]
AnnounceViaNetlink {
message: String,
},
AnnounceViaNetlink { message: String },
#[serde(rename = "remove-device")]
RemoveDevice {
path: String,
},
RemoveDevice { path: String },
}

View file

@ -5,26 +5,17 @@
use super::action::Action;
pub fn handle_cli_action(json: String) -> i32 {
let action: Action = serde_json::from_str(&json)
.expect("invalid action JSON");
handle_action(action).unwrap_or_else(|err|
{
panic!("Error handling action: {}",err);
});
let action: Action = serde_json::from_str(&json).expect("invalid action JSON");
handle_action(action).unwrap_or_else(|err| {
panic!("Error handling action: {}", err);
});
0
}
fn handle_action(action: Action) -> Result<(), String> {
fn handle_action(action: Action) -> Result<(), String> {
match action {
Action::MknodDevice { .. } => {
Ok(())
}
Action::AnnounceViaNetlink { .. } => {
Ok(())
}
Action::RemoveDevice { .. } => {
Ok(())
}
Action::MknodDevice { .. } => Ok(()),
Action::AnnounceViaNetlink { .. } => Ok(()),
Action::RemoveDevice { .. } => Ok(()),
}
}

View file

@ -14,7 +14,14 @@ use async_io::Timer;
use log::debug;
use crate::{
actions::{mknod_input_device::ensure_input_device, netlink_message::send_udev_monitor_message_with_properties, runtime_data::{ensure_udev_structure, read_udev_data, write_udev_data}}, job_engine::job::{Job, JobTarget}, jobs::monitor_udev_job::EVENT_STORE, process_tools::{Pid, RequestingProcess, await_process, run_in_net_and_mnt_namespace}
actions::{
mknod_input_device::ensure_input_device,
netlink_message::send_udev_monitor_message_with_properties,
runtime_data::{ensure_udev_structure, read_udev_data, write_udev_data},
},
job_engine::job::{Job, JobTarget},
jobs::monitor_udev_job::EVENT_STORE,
process_tools::{await_process, run_in_net_and_mnt_namespace, Pid, RequestingProcess},
};
#[derive(Clone, Debug, Copy, PartialOrd, PartialEq)]

View file

@ -11,7 +11,13 @@ use std::{
use log::debug;
use crate::{
actions::{mknod_input_device::remove_input_device, netlink_message::send_udev_monitor_message_with_properties, runtime_data::delete_udev_data}, job_engine::job::{Job, JobTarget}, jobs::monitor_udev_job::EVENT_STORE, process_tools::{Pid, RequestingProcess, await_process, run_in_net_and_mnt_namespace}
actions::{
mknod_input_device::remove_input_device,
netlink_message::send_udev_monitor_message_with_properties, runtime_data::delete_udev_data,
},
job_engine::job::{Job, JobTarget},
jobs::monitor_udev_job::EVENT_STORE,
process_tools::{await_process, run_in_net_and_mnt_namespace, Pid, RequestingProcess},
};
#[derive(Clone, Debug, Copy, PartialOrd, PartialEq)]

View file

@ -68,13 +68,11 @@ struct Args {
fn validate_args(args: &Args) -> Result<(), String> {
// action might only occur alone
match (&args.major,&args.minor,&args.devname,&args.action) {
(None,None,None,Some(_)) => {},
(_,_,_,None) => {},
match (&args.major, &args.minor, &args.devname, &args.action) {
(None, None, None, Some(_)) => {}
(_, _, _, None) => {}
_ => {
return Err(
"--action must not be used in combination with any other argument".into(),
);
return Err("--action must not be used in combination with any other argument".into());
}
}
@ -82,9 +80,7 @@ fn validate_args(args: &Args) -> Result<(), String> {
match (&args.major, &args.minor) {
(Some(_), Some(_)) | (None, None) => {}
_ => {
return Err(
"--major and --minor must be specified together or not at all".into(),
);
return Err("--major and --minor must be specified together or not at all".into());
}
}
@ -107,7 +103,9 @@ fn main() -> std::io::Result<()> {
check_permissions().expect("failed to read the capabilities of the vuinputd process");
let args = Args::parse();
let argv0 = std::env::args_os().next().expect("Couldn't retrieve program name");
let argv0 = std::env::args_os()
.next()
.expect("Couldn't retrieve program name");
if let Err(e) = validate_args(&args) {
eprintln!("Error: {e}");
@ -115,11 +113,10 @@ fn main() -> std::io::Result<()> {
}
if args.action.is_some() {
let error_code=actions::handle_action::handle_cli_action(args.action.unwrap());
let error_code = actions::handle_action::handle_cli_action(args.action.unwrap());
std::process::exit(error_code);
}
initialize_vuinput_state();
VUINPUT_COUNTER.set(AtomicU64::new(3)).expect(
"failed to initialize the counter that provides the values of the CUSE file handles",
@ -144,9 +141,9 @@ fn main() -> std::io::Result<()> {
let vuinput_devicename = match &args.devname {
None => "vuinput",
Some(devname) => devname
Some(devname) => devname,
};
let vuinput_devicename = CString::new(format!("DEVNAME={}",vuinput_devicename)).unwrap();
let vuinput_devicename = CString::new(format!("DEVNAME={}", vuinput_devicename)).unwrap();
let mut dev_info_argv: Vec<*const c_char> = vec![
vuinput_devicename.as_ptr(), // pointer to the C string
@ -155,9 +152,9 @@ fn main() -> std::io::Result<()> {
// setting dev_major and dev_minor to 0 leads to a dynamic assignment of the major and minor, very likely beginning with 234:0
// see in https://www.kernel.org/doc/Documentation/admin-guide/devices.txt
let (major,minor) = match ((&args).major, (&args).minor) {
(Some(major), Some(minor)) => (major,minor),
_ => (0,0)
let (major, minor) = match ((&args).major, (&args).minor) {
(Some(major), Some(minor)) => (major, minor),
_ => (0, 0),
};
let ci = cuse_lowlevel::cuse_info {
dev_major: major,