From 423844d05c4d36253cc5bd4d0a3b144d268dfdba Mon Sep 17 00:00:00 2001 From: r0chd Date: Thu, 25 Jun 2026 14:35:02 +0200 Subject: [PATCH] fix: resolve clippy warnings --- Cargo.toml | 11 ++++ ctl/Cargo.toml | 3 + ctl/build.rs | 9 ++- ctl/src/main.rs | 92 +++++++++++++++++------------- daemon/Cargo.toml | 3 + daemon/build.rs | 9 ++- daemon/src/cgroup.rs | 9 +-- daemon/src/device.rs | 10 ++-- daemon/src/main.rs | 20 ++++--- daemon/src/seat.rs | 102 ++++++++++++++++++---------------- daemon/src/session.rs | 45 +++++++-------- daemon/src/terminal.rs | 37 ++++++------ pam/Cargo.toml | 3 + pam/build.rs | 9 ++- pam/src/lib.rs | 14 +++-- protocols/session_core_v1.xml | 6 +- 16 files changed, 224 insertions(+), 158 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 38c6074..f0c8053 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,3 +22,14 @@ repository = "https://github.com/mox-desktop/sessiond" version = "0.1.0" description = "" readme = "README.md" + +[workspace.lints.clippy] +all = { level = "warn", priority = -1 } +pedantic = { level = "warn", priority = -1 } +nursery = { level = "warn", priority = -1 } +dbg_macro = "warn" +expect_used = "warn" +panic = "warn" +todo = "warn" +unimplemented = "warn" +unwrap_used = "warn" diff --git a/ctl/Cargo.toml b/ctl/Cargo.toml index e7a65ca..4b28d72 100644 --- a/ctl/Cargo.toml +++ b/ctl/Cargo.toml @@ -9,6 +9,9 @@ version.workspace = true description.workspace = true readme.workspace = true +[lints] +workspace = true + [dependencies] anyhow = "1.0.102" clap = { version = "4.6.1", features = ["derive"] } diff --git a/ctl/build.rs b/ctl/build.rs index 0060941..c1792ef 100644 --- a/ctl/build.rs +++ b/ctl/build.rs @@ -1,9 +1,12 @@ -fn main() { +use std::io; + +fn main() -> io::Result<()> { hyprwire_scanner::configure() .with_targets(hyprwire_scanner::Targets::CLIENT) .compile(&[ "../protocols/session_management_v1.xml", "../protocols/session_core_v1.xml", - ]) - .unwrap(); + ])?; + + Ok(()) } diff --git a/ctl/src/main.rs b/ctl/src/main.rs index 1929928..386166e 100644 --- a/ctl/src/main.rs +++ b/ctl/src/main.rs @@ -1,4 +1,6 @@ mod session_core_v1 { + #![allow(clippy::all, clippy::pedantic, clippy::nursery, clippy::unwrap_used)] + hyprwire::include_protocol!("session_core_v1"); pub use client::*; pub use spec::*; @@ -41,35 +43,11 @@ impl hyprwire::Dispatch for State { match event { session_core_manager::Event::Sessions { session_ids } => { for session_id in session_ids { - let session = Session { - id: session_id, - object: object.send_get_session::(session_id).unwrap(), - uid: 0, - username: String::new(), - vt: 0, - seat: None, - leader: 0, - timestamp: 0, - done: false, - active: session_core_v1::ActiveState::Online, - }; - self.sessions.push(session); + self.add_session(object, session_id); } } session_core_manager::Event::SessionAdded { session_id } => { - let session = Session { - id: session_id, - object: object.send_get_session::(session_id).unwrap(), - uid: 0, - username: String::new(), - vt: 0, - seat: None, - leader: 0, - timestamp: 0, - done: false, - active: session_core_v1::ActiveState::Online, - }; - self.sessions.push(session); + self.add_session(object, session_id); } session_core_manager::Event::SessionRemoved { session_id } => { self.sessions.retain(|session| session.id != session_id); @@ -78,6 +56,31 @@ impl hyprwire::Dispatch for State { } } +impl State { + fn add_session(&mut self, manager: &session_core_manager::SessionCoreManager, session_id: u32) { + let Some(object) = manager.send_get_session::(session_id) else { + self.error = Some(format!( + "failed to create session object for id {session_id}" + )); + self.done = true; + return; + }; + + self.sessions.push(Session { + id: session_id, + object, + uid: 0, + username: String::new(), + vt: 0, + seat: None, + leader: 0, + timestamp: 0, + done: false, + active: session_core_v1::ActiveState::Online, + }); + } +} + impl hyprwire::Dispatch for State { fn event( &mut self, @@ -100,7 +103,6 @@ impl hyprwire::Dispatch for State { session_core_session::Event::Leader { leader } => session.leader = leader, session_core_session::Event::Timestamp { timestamp } => session.timestamp = timestamp, session_core_session::Event::Done => session.done = true, - session_core_session::Event::Destroyed => {} session_core_session::Event::Ok => { self.done = true; } @@ -214,7 +216,7 @@ enum SessionAction { } impl SessionAction { - fn from_command(command: &SessionCommand) -> Option { + const fn from_command(command: &SessionCommand) -> Option { match command { SessionCommand::List => None, SessionCommand::Close { .. } => Some(Self::Close), @@ -224,7 +226,7 @@ impl SessionAction { } } - fn ids<'a>(command: &'a SessionCommand) -> Option<&'a [u32]> { + fn ids(command: &SessionCommand) -> Option<&[u32]> { match command { SessionCommand::List => None, SessionCommand::Close { ids, .. } @@ -234,7 +236,7 @@ impl SessionAction { } } - fn targets_current(command: &SessionCommand) -> bool { + const fn targets_current(command: &SessionCommand) -> bool { match command { SessionCommand::List => false, SessionCommand::Close { current, .. } | SessionCommand::Kill { current, .. } => { @@ -254,6 +256,7 @@ impl SessionAction { } } +#[allow(clippy::too_many_lines)] fn main() -> anyhow::Result<()> { let cli = Cli::parse(); @@ -285,6 +288,10 @@ fn main() -> anyhow::Result<()> { event_queue.dispatch_events(&mut state, true)?; } + if let Some(err) = state.error.take() { + anyhow::bail!("{err}"); + } + let Command::Session(command) = &cli.command else { unreachable!(); }; @@ -307,7 +314,7 @@ fn main() -> anyhow::Result<()> { let fmt_ts = |ts: u32| -> String { use std::time::{Duration, UNIX_EPOCH}; - let Some(t) = UNIX_EPOCH.checked_add(Duration::from_secs(ts as u64)) else { + let Some(t) = UNIX_EPOCH.checked_add(Duration::from_secs(u64::from(ts))) else { return String::from("?"); }; let Ok(elapsed) = t.elapsed() else { @@ -318,11 +325,11 @@ fn main() -> anyhow::Result<()> { let m = (s % 3600) / 60; let s = s % 60; if h > 0 { - format!("{}h {}min ago", h, m) + format!("{h}h {m}min ago") } else if m > 0 { - format!("{}min {}s ago", m, s) + format!("{m}min {s}s ago") } else { - format!("{}s ago", s) + format!("{s}s ago") } }; @@ -420,9 +427,16 @@ fn main() -> anyhow::Result<()> { ); } } - command => { - let action = SessionAction::from_command(command).unwrap(); - let ids = SessionAction::ids(command).unwrap(); + command @ (SessionCommand::Close { .. } + | SessionCommand::Kill { .. } + | SessionCommand::Lock { .. } + | SessionCommand::Unlock { .. }) => { + let Some(action) = SessionAction::from_command(command) else { + unreachable!(); + }; + let Some(ids) = SessionAction::ids(command) else { + unreachable!(); + }; if SessionAction::targets_current(command) { let uid = process::getuid(); @@ -444,7 +458,7 @@ fn main() -> anyhow::Result<()> { let mut unmatched = Vec::new(); let mut matched = Vec::new(); - for id in ids.iter() { + for id in ids { if let Some(session) = state.sessions.iter().find(|session| session.id == *id) { matched.push(session.object.clone()); } else { @@ -455,7 +469,7 @@ fn main() -> anyhow::Result<()> { if !unmatched.is_empty() { let ids = unmatched .iter() - .map(|id| id.to_string()) + .map(std::string::ToString::to_string) .collect::>() .join(", "); eprintln!("{} unknown session ids: {ids}", "error:".red()); diff --git a/daemon/Cargo.toml b/daemon/Cargo.toml index 23c4078..87a67f3 100644 --- a/daemon/Cargo.toml +++ b/daemon/Cargo.toml @@ -9,6 +9,9 @@ version.workspace = true description.workspace = true readme.workspace = true +[lints] +workspace = true + [dependencies] anyhow = "1.0.102" clap = { version = "4.6.1", features = ["derive"] } diff --git a/daemon/build.rs b/daemon/build.rs index dd13654..5ec87c2 100644 --- a/daemon/build.rs +++ b/daemon/build.rs @@ -1,10 +1,13 @@ -fn main() { +use std::io; + +fn main() -> io::Result<()> { hyprwire_scanner::configure() .with_targets(hyprwire_scanner::Targets::SERVER) .compile(&[ "../protocols/session_management_v1.xml", "../protocols/session_core_v1.xml", "../protocols/seat_v1.xml", - ]) - .unwrap(); + ])?; + + Ok(()) } diff --git a/daemon/src/cgroup.rs b/daemon/src/cgroup.rs index f84ef55..d6ae749 100644 --- a/daemon/src/cgroup.rs +++ b/daemon/src/cgroup.rs @@ -124,8 +124,9 @@ impl CgroupManager { let procs = fs::read_to_string(cgroup.path.join("cgroup.procs"))?; for line in procs.lines() { let pid = line.trim().parse::()?; + let pid = process::Pid::from_raw(pid).context("invalid pid in cgroup.procs")?; - process::kill_process(process::Pid::from_raw(pid).unwrap(), process::Signal::TERM)?; + process::kill_process(pid, process::Signal::TERM)?; } self.poll_destroy(session_id)?; @@ -134,13 +135,13 @@ impl CgroupManager { } pub fn find_session_by_pid(&self, pid: u32) -> anyhow::Result> { - for cgroup in self.cgroups.iter() { + for cgroup in &self.cgroups { let procs = fs::read_to_string(cgroup.path.join("cgroup.procs"))?; if procs .lines() - .find(|line| *line.trim() == pid.to_string()) - .is_some() + .filter_map(|line| line.trim().parse::().ok()) + .any(|cgroup_pid| cgroup_pid == pid) { return Ok(Some(cgroup.session_id)); } diff --git a/daemon/src/device.rs b/daemon/src/device.rs index 0829802..446a74d 100644 --- a/daemon/src/device.rs +++ b/daemon/src/device.rs @@ -176,15 +176,15 @@ impl Device { self.objects.push(object); } - pub(crate) fn id(&self) -> u32 { + pub(crate) const fn id(&self) -> u32 { self.id } - pub(crate) fn kind(&self) -> DeviceKind { + pub(crate) const fn kind(&self) -> DeviceKind { self.r#type } - pub(crate) fn fd(&self) -> &fd::OwnedFd { + pub(crate) const fn fd(&self) -> &fd::OwnedFd { &self.fd } @@ -194,7 +194,7 @@ impl Device { pub(crate) fn absolute_path_string(&self) -> String { path::absolute(&self.path) - .unwrap_or(self.path.clone()) + .unwrap_or_else(|_| self.path.clone()) .display() .to_string() } @@ -217,7 +217,7 @@ impl Device { } } - pub(crate) fn decrement_ref(&mut self) -> usize { + pub(crate) const fn decrement_ref(&mut self) -> usize { self.ref_cnt = self.ref_cnt.saturating_sub(1); self.ref_cnt } diff --git a/daemon/src/main.rs b/daemon/src/main.rs index 2a9b44a..3921523 100644 --- a/daemon/src/main.rs +++ b/daemon/src/main.rs @@ -1,13 +1,19 @@ mod session_management_v1 { + #![allow(clippy::all, clippy::pedantic, clippy::nursery, clippy::unwrap_used)] + hyprwire::include_protocol!("session_management_v1"); pub use server::*; } mod session_core_v1 { + #![allow(clippy::all, clippy::pedantic, clippy::nursery, clippy::unwrap_used)] + hyprwire::include_protocol!("session_core_v1"); pub use server::*; pub use spec::*; } mod seat_v1 { + #![allow(clippy::all, clippy::pedantic, clippy::nursery, clippy::unwrap_used)] + hyprwire::include_protocol!("seat_v1"); pub use server::*; pub use spec::*; @@ -54,7 +60,7 @@ struct SeatAccess { } impl SeatAccess { - fn new(user: process::Uid, group: process::Gid) -> Self { + const fn new(user: process::Uid, group: process::Gid) -> Self { Self { user, group } } @@ -63,11 +69,11 @@ impl SeatAccess { return true; } - self.process_groups(creds.pid.as_raw_pid() as u32) + Self::process_groups(creds.pid.as_raw_pid().cast_unsigned()) .is_ok_and(|groups| groups.contains(&self.group)) } - fn process_groups(&self, pid: u32) -> anyhow::Result> { + fn process_groups(pid: u32) -> anyhow::Result> { let status = fs::read_to_string(format!("/proc/{pid}/status"))?; let Some(groups) = status.lines().find_map(|line| line.strip_prefix("Groups:")) else { return Ok(Vec::new()); @@ -249,7 +255,7 @@ impl hyprwire::Dispatch for Sessiond { log::info!(session_id = session_id.as_raw(), uid = session.uid(), username = session.username(); "session destroyed"); session.set_state(session_core_v1::ActiveState::Closing); - for object in session.objects().iter() { + for object in session.objects() { object.send_destroyed(); } @@ -347,6 +353,7 @@ impl hyprwire::Dispatch for Sessiond { } } +#[allow(clippy::too_many_lines)] fn main() -> anyhow::Result<()> { let args = Args::parse(); @@ -417,13 +424,12 @@ fn main() -> anyhow::Result<()> { .insert_source(source, move |_, _, state| { _ = socket.dispatch_events(state, false); Ok(calloop::PostAction::Continue) - }) - .unwrap(); + })?; let signals = signals::Signals::new(&[signals::Signal::SIGUSR1, signals::Signal::SIGUSR2])?; event_loop .handle() - .insert_source(signals, move |event, _, state| { + .insert_source(signals, move |event, (), state| { let mut session_updates = Vec::new(); for seat in state.seat.iter_mut().filter(|seat| seat.is_vt_bound()) { diff --git a/daemon/src/seat.rs b/daemon/src/seat.rs index 84903ec..cb0bae7 100644 --- a/daemon/src/seat.rs +++ b/daemon/src/seat.rs @@ -10,7 +10,7 @@ impl seat_v1::SeatV1Handler for crate::Sessiond { fn bind(&mut self, object: seat_manager::SeatManager) { let Some(client) = object.client() else { object.error( - io::Errno::PERM.raw_os_error() as u32, + io::Errno::PERM.raw_os_error().cast_unsigned(), "seat access requires peer credentials", ); return; @@ -27,7 +27,10 @@ impl seat_v1::SeatV1Handler for crate::Sessiond { gid = creds.gid.as_raw(); "rejected seat_v1 bind from unauthorized client" ); - object.error(io::Errno::PERM.raw_os_error() as u32, "seat access denied"); + object.error( + io::Errno::PERM.raw_os_error().cast_unsigned(), + "seat access denied", + ); } } @@ -41,7 +44,7 @@ impl hyprwire::Dispatch for crate::Sessiond { seat_manager::Event::OpenSeat { seat } => { let Some(server_client) = object.client() else { seat.error( - io::Errno::PERM.raw_os_error() as u32, + io::Errno::PERM.raw_os_error().cast_unsigned(), "seat access requires peer credentials", ); return; @@ -55,12 +58,15 @@ impl hyprwire::Dispatch for crate::Sessiond { gid = creds.gid.as_raw(); "rejected seat open from unauthorized client" ); - seat.error(io::Errno::PERM.raw_os_error() as u32, "seat access denied"); + seat.error( + io::Errno::PERM.raw_os_error().cast_unsigned(), + "seat access denied", + ); return; } let session_id = { - let pid = server_client.creds().pid.as_raw_pid() as u32; + let pid = server_client.creds().pid.as_raw_pid().cast_unsigned(); match self.cgroup_manager.find_session_by_pid(pid) { Ok(session_id) => session_id, Err(err) => { @@ -89,7 +95,7 @@ impl hyprwire::Dispatch for crate::Sessiond { client.borrow().object.send_disabled(); return; } - if let Err(err) = seat.open_client(rc::Rc::clone(&client)) { + if let Err(err) = seat.open_client(&client) { log::error!("Could not open client on seat: {err}"); let _ = seat.remove_client(&client); client.borrow().object.send_disabled(); @@ -117,6 +123,7 @@ impl hyprwire::Dispatch for crate::Sessiond { } impl hyprwire::Dispatch for crate::Sessiond { + #[allow(clippy::too_many_lines)] fn event(&mut self, object: &seat::Seat, event: ::Event<'_>) { let Some(client) = self .clients @@ -154,14 +161,14 @@ impl hyprwire::Dispatch for crate::Sessiond { seat::Event::OpenDevice { device, path } => { let seat_name = client.borrow().seat_name.clone(); let Some(seat) = self.seat.iter().find(|seat| seat.name() == seat_name) else { - log::error!("No shared seat found for {}", seat_name); + log::error!("No shared seat found for {seat_name}"); return; }; if !seat.is_active_client(&client) { device.send_failed( seat_v1::DeviceError::SeatDisabled, - io::Errno::PERM.raw_os_error() as u32, + io::Errno::PERM.raw_os_error().cast_unsigned(), "open_device is only valid for the active seat client", ); return; @@ -172,7 +179,7 @@ impl hyprwire::Dispatch for crate::Sessiond { let Ok(sanitized_path) = fs::canonicalize(path) else { device.send_failed( seat_v1::DeviceError::OpenFailed, - io::Errno::NOENT.raw_os_error() as u32, + io::Errno::NOENT.raw_os_error().cast_unsigned(), "could not canonicalize device path", ); return; @@ -181,7 +188,7 @@ impl hyprwire::Dispatch for crate::Sessiond { if client.state != crate::seat::SeatState::Enabled { device.send_failed( seat_v1::DeviceError::SeatDisabled, - io::Errno::BUSY.raw_os_error() as u32, + io::Errno::BUSY.raw_os_error().cast_unsigned(), "open_device is only valid while the seat is enabled", ); return; @@ -194,7 +201,7 @@ impl hyprwire::Dispatch for crate::Sessiond { ); device.send_failed( seat_v1::DeviceError::OpenFailed, - io::Errno::INVAL.raw_os_error() as u32, + io::Errno::INVAL.raw_os_error().cast_unsigned(), "unsupported device type", ); return; @@ -206,20 +213,21 @@ impl hyprwire::Dispatch for crate::Sessiond { .find(|device| device.matches_path(&sanitized_path)) { old_device.add_object(device); - let object = old_device.last_object().unwrap(); - object.send_opened( - old_device.id(), - old_device.fd().as_fd(), - old_device.absolute_path_string(), - ); + if let Some(object) = old_device.last_object() { + object.send_opened( + old_device.id(), + old_device.fd().as_fd(), + old_device.absolute_path_string(), + ); + } return; } - if client.devices.len() as u8 >= MAX_SEAT_DEVICES { + if client.devices.len() >= usize::from(MAX_SEAT_DEVICES) { log::error!("Client exceeded max seat devices"); device.send_failed( seat_v1::DeviceError::OpenFailed, - io::Errno::MFILE.raw_os_error() as u32, + io::Errno::MFILE.raw_os_error().cast_unsigned(), "client exceeded max seat devices", ); return; @@ -228,7 +236,7 @@ impl hyprwire::Dispatch for crate::Sessiond { let device_id = client .devices .iter() - .map(|device| device.id()) + .map(device::Device::id) .max() .map_or(1, |id| id + 1); @@ -246,22 +254,19 @@ impl hyprwire::Dispatch for crate::Sessiond { log::error!("Could not open file: {e}"); device.send_failed( seat_v1::DeviceError::OpenFailed, - e.raw_os_error() as u32, + e.raw_os_error().cast_unsigned(), "could not open device", ); return; } }; - let mut seat_device = crate::device::Device::new( + let mut seat_device = device::Device::new( device, - sanitized_path.clone(), + sanitized_path, kind, device_id, - matches!( - kind, - crate::device::DeviceKind::Evdev | crate::device::DeviceKind::Hidraw - ), + matches!(kind, device::DeviceKind::Evdev | device::DeviceKind::Hidraw), fd, ); @@ -272,19 +277,23 @@ impl hyprwire::Dispatch for crate::Sessiond { .downcast_ref::() .copied() .unwrap_or(io::Errno::INVAL); - seat_device.last_object().unwrap().send_failed( - seat_v1::DeviceError::OpenFailed, - errno.raw_os_error() as u32, - "could not activate device", - ); + if let Some(object) = seat_device.last_object() { + object.send_failed( + seat_v1::DeviceError::OpenFailed, + errno.raw_os_error().cast_unsigned(), + "could not activate device", + ); + } return; } - seat_device.last_object().unwrap().send_opened( - device_id, - seat_device.fd().as_fd(), - seat_device.absolute_path_string(), - ); + if let Some(object) = seat_device.last_object() { + object.send_opened( + device_id, + seat_device.fd().as_fd(), + seat_device.absolute_path_string(), + ); + } client.devices.push(seat_device); } seat::Event::SwitchSession { session } => { @@ -336,7 +345,7 @@ pub struct Seat { impl Default for Seat { fn default() -> Self { - Seat { + Self { name: "seat0".to_string(), clients: Vec::new(), active_client: None, @@ -349,7 +358,7 @@ impl Default for Seat { impl Seat { pub fn vt_bound(name: String) -> Self { - log::info!("Created VT-bound seat {}", name); + log::info!("Created VT-bound seat {name}"); Self { name, kind: SeatKind::VtBound, @@ -424,7 +433,7 @@ impl Seat { pub fn vt_switch(&self, vt: u32) -> anyhow::Result<()> { let terminal = terminal::Terminal::open(self.cur_vt)?; terminal.set_process_switching(true)?; - terminal.switch_vt(vt as i32)?; + terminal.switch_vt(vt)?; Ok(()) } @@ -469,8 +478,7 @@ impl Seat { let released_vt = self .active_client .as_ref() - .map(|client| client.borrow().session_id) - .unwrap_or(self.cur_vt); + .map_or(self.cur_vt, |client| client.borrow().session_id); log::debug!("Releasing VT"); if let Some(active_client) = self.active_client.clone() { @@ -515,7 +523,7 @@ impl Seat { }; if let Some(client) = next_client { - self.open_client(client)?; + self.open_client(&client)?; } Ok(()) @@ -523,7 +531,7 @@ impl Seat { pub fn open_client( &mut self, - client: rc::Rc>, + client: &rc::Rc>, ) -> anyhow::Result<()> { debug_assert_eq!(client.borrow().seat_name, self.name); @@ -559,7 +567,7 @@ impl Seat { client.borrow().object.send_enabled(); client.borrow_mut().state = SeatState::Enabled; - self.active_client = Some(rc::Rc::clone(&client)); + self.active_client = Some(rc::Rc::clone(client)); log::info!( "Opened client {} on {}", client.borrow().session_id, @@ -626,7 +634,7 @@ impl Seat { client.borrow_mut().session_id = next_session; } - client.borrow_mut().seat_name = self.name.clone(); + client.borrow_mut().seat_name.clone_from(&self.name); log::info!( "Added client {} to {}", client.borrow().session_id, @@ -638,7 +646,7 @@ impl Seat { } pub fn disable_client( - &mut self, + &self, client: &rc::Rc>, ) -> anyhow::Result<()> { if client.borrow().state != SeatState::Enabled { diff --git a/daemon/src/session.rs b/daemon/src/session.rs index 962f515..972dc54 100644 --- a/daemon/src/session.rs +++ b/daemon/src/session.rs @@ -5,15 +5,15 @@ use std::time; pub struct SessionId(u32); impl SessionId { - pub fn as_raw(self) -> u32 { + pub const fn as_raw(self) -> u32 { self.0 } - pub fn from_raw(id: u32) -> Self { + pub const fn from_raw(id: u32) -> Self { Self(id) } - pub fn next(self) -> Self { + pub const fn next(self) -> Self { Self(self.0.wrapping_add(1)) } } @@ -45,7 +45,7 @@ impl Session { } } - pub fn vt(&self) -> u32 { + pub const fn vt(&self) -> u32 { self.vt } @@ -53,11 +53,11 @@ impl Session { &self.username } - pub fn uid(&self) -> u32 { + pub const fn uid(&self) -> u32 { self.uid } - pub fn id(&self) -> SessionId { + pub const fn id(&self) -> SessionId { self.id } @@ -65,14 +65,14 @@ impl Session { &self.objects } - pub fn state(&self) -> session_core_v1::ActiveState { + pub const fn state(&self) -> session_core_v1::ActiveState { self.state } pub fn set_state(&mut self, state: session_core_v1::ActiveState) { log::info!(session_id = self.id.as_raw(), vt = self.vt; "session state changed"); self.state = state; - for object in self.objects.iter() { + for object in &self.objects { object.send_active(self.state); } } @@ -86,14 +86,14 @@ impl Session { self.seat = Some(seat); if let Some(seat) = self.seat.as_ref() { - for object in self.objects.iter() { + for object in &self.objects { object.send_seat(seat); } } } pub fn add_object(&mut self, object: session_core_session::SessionCoreSession) { - log::debug!(session_id = self.id.as_raw(), uid = object.client().map(|c| c.creds().uid.as_raw()).unwrap_or(0); "session info requested"); + log::debug!(session_id = self.id.as_raw(), uid = object.client().map_or(0, |c| c.creds().uid.as_raw()); "session info requested"); object.send_session_id(self.id.as_raw()); object.send_uid(self.uid); object.send_username(&self.username); @@ -102,13 +102,14 @@ impl Session { if let Some(seat) = self.seat.as_ref() { object.send_seat(seat); } - object.send_leader(self.leader_id as u32); - object.send_timestamp( - self.timestamp - .duration_since(time::UNIX_EPOCH) - .unwrap_or_default() - .as_secs() as u32, - ); + object.send_leader(self.leader_id.cast_unsigned()); + let timestamp_secs = self + .timestamp + .duration_since(time::UNIX_EPOCH) + .unwrap_or_default() + .as_secs(); + let timestamp = u32::try_from(timestamp_secs).unwrap_or(u32::MAX); + object.send_timestamp(timestamp); object.send_done(); self.objects.push(object); @@ -130,7 +131,7 @@ impl hyprwire::Dispatch for crate::Ses return; }; - if let session_core_session::Event::Destroy = event { + if matches!(event, session_core_session::Event::Destroy) { self.sessions[idx] .objects .retain(|session_object| session_object != object); @@ -153,7 +154,7 @@ impl hyprwire::Dispatch for crate::Ses let session = self.sessions.swap_remove(idx); log::info!(session_id = session.id.as_raw(); "terminate requested"); - for obj in session.objects.iter() { + for obj in &session.objects { obj.send_active(session_core_v1::ActiveState::Closing); } if let Err(err) = self.cgroup_manager.terminate_session(session.id) { @@ -162,7 +163,7 @@ impl hyprwire::Dispatch for crate::Ses } session_core_session::Event::Kill => { log::info!(session_id = self.sessions[idx].id.as_raw(); "kill requested"); - for obj in self.sessions[idx].objects.iter() { + for obj in &self.sessions[idx].objects { obj.send_active(session_core_v1::ActiveState::Closing); } if let Err(err) = self.cgroup_manager.kill_session(self.sessions[idx].id) { @@ -172,14 +173,14 @@ impl hyprwire::Dispatch for crate::Ses } session_core_session::Event::Lock => { log::info!(session_id = self.sessions[idx].id.as_raw(); "lock requested"); - for object in self.sessions[idx].objects.iter() { + for object in &self.sessions[idx].objects { object.send_locked(); object.send_ok(); } } session_core_session::Event::Unlock => { log::info!(session_id = self.sessions[idx].id.as_raw(); "unlock requested"); - for object in self.sessions[idx].objects.iter() { + for object in &self.sessions[idx].objects { object.send_unlocked(); object.send_ok(); } diff --git a/daemon/src/terminal.rs b/daemon/src/terminal.rs index f9d829d..1f5bd1d 100644 --- a/daemon/src/terminal.rs +++ b/daemon/src/terminal.rs @@ -4,6 +4,7 @@ use std::{fs, path}; #[repr(C)] #[derive(Debug, Copy, Clone)] +#[allow(clippy::struct_field_names)] struct VtStat { v_active: u16, v_signal: u16, @@ -28,11 +29,11 @@ const KDSETMODE: ioctl::Opcode = 0x4B3A; const KDSKBMODE: ioctl::Opcode = 0x4B45; const VT_AUTO: u8 = 0x00; const VT_PROCESS: u8 = 0x01; -const VT_ACKACQ: i32 = 0x02; -const KD_TEXT: i32 = 0x00; -const KD_GRAPHICS: i32 = 0x01; -const K_UNICODE: i32 = 0x03; -const K_OFF: i32 = 0x04; +const VT_ACKACQ: usize = 0x02; +const KD_TEXT: usize = 0x00; +const KD_GRAPHICS: usize = 0x01; +const K_UNICODE: usize = 0x03; +const K_OFF: usize = 0x04; const FRSIG: i16 = 0; pub struct Terminal(fs::File); @@ -60,12 +61,12 @@ impl Terminal { mode: if enable { VT_PROCESS } else { VT_AUTO }, waitv: 0, relsig: if enable { - process::Signal::USR1.as_raw() as i16 + i16::try_from(process::Signal::USR1.as_raw())? } else { 0 }, acqsig: if enable { - process::Signal::USR2.as_raw() as i16 + i16::try_from(process::Signal::USR2.as_raw())? } else { 0 }, @@ -87,13 +88,13 @@ impl Terminal { Ok(()) } - pub fn switch_vt(&self, vt: i32) -> anyhow::Result<()> { + pub fn switch_vt(&self, vt: u32) -> anyhow::Result<()> { log::debug!("Switching to VT {vt}"); let result = unsafe { ioctl::ioctl( &self.0, - ioctl::IntegerSetter::::new_usize(vt as usize), + ioctl::IntegerSetter::::new_usize(usize::try_from(vt)?), ) }; @@ -125,7 +126,7 @@ impl Terminal { let result = unsafe { ioctl::ioctl( &self.0, - ioctl::IntegerSetter::::new_usize(VT_ACKACQ as usize), + ioctl::IntegerSetter::::new_usize(VT_ACKACQ), ) }; @@ -143,9 +144,11 @@ impl Terminal { let result = unsafe { ioctl::ioctl( &self.0, - ioctl::IntegerSetter::::new_usize( - (if enable { K_UNICODE } else { K_OFF }) as usize, - ), + ioctl::IntegerSetter::::new_usize(if enable { + K_UNICODE + } else { + K_OFF + }), ) }; @@ -167,9 +170,11 @@ impl Terminal { let result = unsafe { ioctl::ioctl( &self.0, - ioctl::IntegerSetter::::new_usize( - (if enable { KD_GRAPHICS } else { KD_TEXT }) as usize, - ), + ioctl::IntegerSetter::::new_usize(if enable { + KD_GRAPHICS + } else { + KD_TEXT + }), ) }; diff --git a/pam/Cargo.toml b/pam/Cargo.toml index 51a74bf..8cd41b4 100644 --- a/pam/Cargo.toml +++ b/pam/Cargo.toml @@ -12,6 +12,9 @@ readme.workspace = true [lib] crate-type = ["cdylib"] +[lints] +workspace = true + [dependencies] pamsm = { git = "https://github.com/r0chd/pam_sm_rust", rev = "a86b725689e402ab3eec6c265e7d82b74b7f9227", features = [ "libpam", diff --git a/pam/build.rs b/pam/build.rs index 9b5b5a3..37a2c42 100644 --- a/pam/build.rs +++ b/pam/build.rs @@ -1,6 +1,9 @@ -fn main() { +use std::io; + +fn main() -> io::Result<()> { hyprwire_scanner::configure() .with_targets(hyprwire_scanner::Targets::CLIENT) - .compile(&["../protocols/session_management_v1.xml"]) - .unwrap(); + .compile(&["../protocols/session_management_v1.xml"])?; + + Ok(()) } diff --git a/pam/src/lib.rs b/pam/src/lib.rs index 4e8d837..48c1d4a 100644 --- a/pam/src/lib.rs +++ b/pam/src/lib.rs @@ -1,4 +1,6 @@ mod session_management_v1 { + #![allow(clippy::all, clippy::pedantic, clippy::nursery, clippy::unwrap_used)] + hyprwire::include_protocol!("session_management_v1"); pub use client::*; } @@ -20,7 +22,7 @@ impl hyprwire::Dispatch for Session { ) { let session_manager::Event::SessionCreated { session_id, seat } = event; self.session_id = Some(session_id); - self.seat = Some(seat.to_string()); + self.seat = Some(seat); } } @@ -28,7 +30,7 @@ struct Pam; impl PamServiceModule for Pam { fn open_session(pamh: pamsm::Pam, _: pamsm::PamFlags, _: Vec) -> pamsm::PamError { - fn inner(pamh: pamsm::Pam) -> Result<(), pamsm::PamError> { + fn inner(pamh: &pamsm::Pam) -> Result<(), pamsm::PamError> { let mut session = Session { session_id: None, seat: None, @@ -74,7 +76,7 @@ impl PamServiceModule for Pam { .map_err(|_| pamsm::PamError::SESSION_ERR)?; } - let session_id = session.session_id.unwrap(); + let session_id = session.session_id.ok_or(pamsm::PamError::SESSION_ERR)?; pamh.send_bytes("sessiond", session_id.to_le_bytes().to_vec(), None) .map_err(|_| pamsm::PamError::SESSION_ERR)?; @@ -87,14 +89,14 @@ impl PamServiceModule for Pam { Ok(()) } - match inner(pamh) { + match inner(&pamh) { Ok(()) => pamsm::PamError::SUCCESS, Err(e) => e, } } fn close_session(pamh: pamsm::Pam, _: pamsm::PamFlags, _: Vec) -> pamsm::PamError { - fn inner(pamh: pamsm::Pam) -> Result<(), pamsm::PamError> { + fn inner(pamh: &pamsm::Pam) -> Result<(), pamsm::PamError> { let session_id = pamh .retrieve_bytes("sessiond") .map_err(|_| pamsm::PamError::SESSION_ERR) @@ -129,7 +131,7 @@ impl PamServiceModule for Pam { Ok(()) } - match inner(pamh) { + match inner(&pamh) { Ok(()) => pamsm::PamError::SUCCESS, Err(e) => e, } diff --git a/protocols/session_core_v1.xml b/protocols/session_core_v1.xml index 60c8496..c09b34a 100644 --- a/protocols/session_core_v1.xml +++ b/protocols/session_core_v1.xml @@ -24,7 +24,7 @@ - Creates a session_core_session object for the given session_id. + Creates a `session_core_session` object for the given session_id. The daemon immediately pushes all fields, followed by done. If the session does not exist, destroyed is sent instead. @@ -94,8 +94,8 @@ - Sent when the session is destroyed or if the session_id passed to - get_session was not found. The client should release this object. + Sent when the session is destroyed or if the `session_id` passed to + `get_session` was not found. The client should release this object. -- 2.51.2