diff --git a/Cargo.toml b/Cargo.toml index cbc542d..6058c9f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,6 +13,6 @@ itertools = "0.13.0" libc = "0.2.155" libsystemd-sys = "0.9.3" log = "0.4.22" -nix = { version = "0.29.0", features = ["fs"] } +nix = { version = "0.29.0", features = ["fs", "process", "signal"] } wayland-client = { version = "0.31.5", features = ["log"] } wayland-sys = { version = "0.31.4", features = ["client", "server"] } diff --git a/src/main.rs b/src/main.rs index 481ea86..1dd24bd 100644 --- a/src/main.rs +++ b/src/main.rs @@ -7,11 +7,11 @@ use std::{ borrow::Cow, env, - ffi::{CStr, CString}, + ffi::{c_char, c_int, c_void, CStr, CString}, fs::File, io::{BufRead, BufReader}, - mem::{self, MaybeUninit}, - os::raw::c_void, + mem, + os::fd::RawFd, path::Path, process, ptr, }; @@ -19,10 +19,7 @@ use std::{ use ext_idle_notify_v1_protocol::{ ext_idle_notification_v1_interface, ext_idle_notifier_v1_interface, }; -use libc::{ - __errno_location, abort, calloc, close, execvp, exit, fork, getenv, getopt, getpid, - sigemptyset, signal, sigprocmask, sigset_t, size_t, sprintf, strcmp, strdup, strstr, waitpid, -}; +use libc::{getopt, size_t, strcmp, strstr}; use libsystemd_sys::bus::{ sd_bus, sd_bus_call_method, sd_bus_default_system, sd_bus_error, sd_bus_error_free, sd_bus_flush, sd_bus_get_fd, sd_bus_get_property, sd_bus_message, @@ -30,7 +27,16 @@ use libsystemd_sys::bus::{ sd_bus_message_read, sd_bus_message_read_basic, sd_bus_message_skip, sd_bus_message_unref, sd_bus_process, sd_bus_slot, }; -use nix::unistd::AccessFlags; +use log::LevelFilter; +use nix::{ + errno::Errno, + fcntl::FcntlArg, + sys::{ + signal::{SigHandler, SigSet, SigmaskHow, Signal}, + wait::WaitStatus, + }, + unistd::{AccessFlags, ForkResult, Pid}, +}; use wayland_client::protocol::__interfaces::{wl_registry_interface, wl_seat_interface}; use wayland_sys::{ client::{ @@ -69,8 +75,8 @@ type ext_idle_notifier_v1 = wl_interface; unused_mut )] extern "C" { - static mut optind: libc::c_int; - static mut optarg: *mut libc::c_char; + static mut optind: c_int; + static mut optarg: *mut c_char; fn wl_proxy_marshal_flags( proxy: *mut wl_proxy, opcode: u32, @@ -82,33 +88,26 @@ extern "C" { fn sd_bus_match_signal( bus_0: *mut sd_bus, ret: *mut *mut sd_bus_slot, - sender: *const libc::c_char, - path: *const libc::c_char, - interface: *const libc::c_char, - member: *const libc::c_char, + sender: *const c_char, + path: *const c_char, + interface: *const c_char, + member: *const c_char, callback: sd_bus_message_handler_t, - userdata: *mut libc::c_void, - ) -> libc::c_int; + userdata: *mut c_void, + ) -> c_int; } #[derive(Copy, Clone)] #[repr(C)] struct wl_registry_listener { - global: Option< - unsafe extern "C" fn( - *mut libc::c_void, - *mut wl_registry, - u32, - *const libc::c_char, - u32, - ) -> (), - >, - global_remove: Option ()>, + global: + Option ()>, + global_remove: Option ()>, } #[derive(Copy, Clone)] #[repr(C)] struct wl_seat_listener { - capabilities: Option ()>, - name: Option ()>, + capabilities: Option ()>, + name: Option ()>, } const WL_EVENT_ERROR: u32 = 8; const WL_EVENT_HANGUP: u32 = 4; @@ -117,15 +116,9 @@ const WL_EVENT_READABLE: u32 = 1; #[derive(Copy, Clone)] #[repr(C)] struct ext_idle_notification_v1_listener { - idled: Option ()>, - resumed: Option ()>, + idled: Option ()>, + resumed: Option ()>, } -type log_importance = libc::c_uint; -const LOG_DEBUG: log_importance = 3; -#[allow(dead_code)] -const LOG_INFO: log_importance = 2; -const LOG_ERROR: log_importance = 1; -const LOG_SILENT: log_importance = 0; #[repr(C)] struct swayidle_state { display: *mut wl_display, @@ -144,8 +137,8 @@ struct swayidle_state { #[repr(C)] struct swayidle_timeout_cmd { link: wl_list, - timeout: libc::c_int, - registered_timeout: libc::c_int, + timeout: c_int, + registered_timeout: c_int, idle_notification: *mut ext_idle_notification_v1, idle_cmd: Option, resume_cmd: Option, @@ -156,9 +149,22 @@ struct swayidle_timeout_cmd { struct seat { link: wl_list, proxy: *mut wl_seat, - name: *mut libc::c_char, + name: String, capabilities: u32, } +impl seat { + fn new() -> Self { + Self { + link: wl_list { + prev: ptr::null_mut(), + next: ptr::null_mut(), + }, + proxy: ptr::null_mut(), + name: String::new(), + capabilities: 0, + } + } +} #[inline] unsafe fn wl_display_get_registry(wl_display: *mut wl_display) -> *mut wl_registry { wl_proxy_marshal_flags( @@ -175,8 +181,8 @@ unsafe fn wl_display_get_registry(wl_display: *mut wl_display) -> *mut wl_regist unsafe fn wl_registry_add_listener( wl_registry: *mut wl_registry, listener: *mut wl_registry_listener, - data: *mut libc::c_void, -) -> libc::c_int { + data: *mut c_void, +) -> c_int { wl_proxy_add_listener(wl_registry.cast(), listener.cast(), data) } #[inline] @@ -185,7 +191,7 @@ unsafe fn wl_registry_bind( name: u32, interface: *const wl_interface, version: u32, -) -> *mut libc::c_void { +) -> *mut c_void { wl_proxy_marshal_flags( wl_registry.cast(), 0, @@ -203,8 +209,8 @@ unsafe fn wl_registry_bind( unsafe fn wl_seat_add_listener( wl_seat: *mut wl_seat, listener: *const wl_seat_listener, - data: *mut libc::c_void, -) -> libc::c_int { + data: *mut c_void, +) -> c_int { wl_proxy_add_listener(wl_seat.cast(), listener.cast_mut().cast(), data) } #[inline] @@ -229,8 +235,8 @@ unsafe fn ext_idle_notifier_v1_get_idle_notification( unsafe fn ext_idle_notification_v1_add_listener( ext_idle_notification_v1: *mut ext_idle_notification_v1, listener: *const ext_idle_notification_v1_listener, - data: *mut libc::c_void, -) -> libc::c_int { + data: *mut c_void, +) -> c_int { wl_proxy_add_listener( ext_idle_notification_v1.cast(), listener.cast_mut().cast(), @@ -271,18 +277,8 @@ static mut state: swayidle_state = swayidle_state { timeouts_enabled: false, wait: false, }; -unsafe fn swayidle_log_init(verbosity: log_importance) { - env_logger::builder() - .filter( - None, - match verbosity { - LOG_ERROR => log::LevelFilter::Error, - LOG_SILENT => log::LevelFilter::Off, - LOG_DEBUG => log::LevelFilter::Debug, - _ => log::LevelFilter::Info, - }, - ) - .init(); +unsafe fn swayidle_log_init(verbosity: LevelFilter) { + let _ = env_logger::builder().filter(None, verbosity).try_init(); } impl swayidle_state { unsafe fn init(&mut self) { @@ -299,59 +295,65 @@ impl swayidle_state { tmp = (*cmd).link.next.cast(); } } - unsafe fn sway_terminate(&self, exit_code: libc::c_int) -> ! { + unsafe fn sway_terminate(&self, exit_code: c_int) -> ! { wl_display_disconnect(self.display); wl_event_loop_destroy(self.event_loop); - exit(exit_code); + process::exit(exit_code); } unsafe fn cmd_exec(&self, param: &str) { log::debug!("Cmd exec {param}"); - let mut pid = fork(); - match pid { - 0 => { - if !self.wait { - pid = fork(); - } + match nix::unistd::fork() { + Ok(ForkResult::Child) => { + let pid = if self.wait { + Ok(ForkResult::Child) + } else { + nix::unistd::fork() + }; match pid { - 0 => { - #[allow(clippy::uninit_assumed_init, invalid_value)] - let mut set = MaybeUninit::::uninit().assume_init(); - sigemptyset(ptr::addr_of_mut!(set)); - sigprocmask(2, &set, ptr::null_mut()); - signal(2, 0); - signal(15, 0); - signal(10, 0); + Ok(ForkResult::Child) => { + let set = SigSet::empty(); + let _ = nix::sys::signal::sigprocmask( + SigmaskHow::SIG_SETMASK, + Some(&set), + None, + ); + let _ = nix::sys::signal::signal(Signal::SIGINT, SigHandler::SigDfl); + let _ = nix::sys::signal::signal(Signal::SIGTERM, SigHandler::SigDfl); + let _ = nix::sys::signal::signal(Signal::SIGUSR1, SigHandler::SigDfl); let param = CString::new(param).unwrap(); - let cmd: [*const libc::c_char; 4] = [ - b"sh\0".as_ptr().cast(), - b"-c\0".as_ptr().cast(), - param.as_ptr(), - ptr::null(), + let cmd = [ + CStr::from_bytes_with_nul_unchecked(b"sh\0"), + CStr::from_bytes_with_nul_unchecked(b"-c\0"), + ¶m, ]; - execvp(cmd[0], cmd.as_ptr()); - log::error!("execve failed!: {}", strerror(*__errno_location()),); - exit(1); + let err = match nix::unistd::execvp(cmd[0], &cmd) { + Err(err) => err, + Ok(res) => match res {}, + }; + log::error!("execve failed!: {}", err.desc()); + process::exit(1); } - pid if pid < 0 => { - log::error!("fork failed: {}", strerror(*__errno_location()),); - exit(1); + Err(err) => { + log::error!("fork failed: {}", err.desc()); + process::exit(1); } _ => {} } - exit(0); + process::exit(0); } - pid if pid < 0 => { - log::error!("fork failed: {}", strerror(*__errno_location()),); + Err(err) => { + log::error!("fork failed: {}", err.desc()); } - _ => { + Ok(ForkResult::Parent { child: pid }) => { log::debug!("Spawned process {param}"); if self.wait { log::debug!("Blocking until process exits"); } - let mut status = 0; - waitpid(pid, &mut status, 0); - if i32::from(self.wait) != 0 && status & 0x7f == 0 { - log::debug!("Process exit status: {}", (status & 0xff00) >> 8,); + let status = nix::sys::wait::waitpid(pid, None); + if self.wait { + if let Ok(WaitStatus::Exited(_, status)) = status { + log::debug!("Process exit status: {status}"); + } } } }; @@ -359,11 +361,8 @@ impl swayidle_state { unsafe fn connect_to_bus(&self) { let ret = sd_bus_default_system(ptr::addr_of_mut!(bus)); if ret < 0 { - *__errno_location() = -ret; - log::error!( - "Failed to open D-Bus connection: {}", - strerror(*__errno_location()), - ); + Errno::set_raw(-ret); + log::error!("Failed to open D-Bus connection: {}", Errno::last().desc()); return; } let source = wl_event_loop_add_fd( @@ -376,7 +375,7 @@ impl swayidle_state { wl_event_source_check(source); set_session(); } - unsafe fn display_event(&self, mask: u32) -> libc::c_int { + unsafe fn display_event(&self, mask: u32) -> c_int { if mask & WL_EVENT_HANGUP != 0 || mask & WL_EVENT_ERROR != 0 { self.sway_terminate(0); } @@ -395,13 +394,13 @@ impl swayidle_state { if count < 0 { log::error!( "wl_display_dispatch failed, exiting: {}", - strerror(*__errno_location()), + Errno::last().desc() ); self.sway_terminate(0); } count } - unsafe fn handle_signal(&self, sig: libc::c_int) -> libc::c_int { + unsafe fn handle_signal(&self, sig: c_int) -> c_int { let mut cmd: *mut swayidle_timeout_cmd; match sig { 2 | 15 => { @@ -426,15 +425,15 @@ impl swayidle_state { } _ => {} } - abort(); + process::abort(); } unsafe fn parse_args( &mut self, argc: usize, - argv: *mut *mut libc::c_char, + argv: *mut *mut c_char, config_path: &mut Option, - ) -> libc::c_int { - let mut c: libc::c_int; + ) -> c_int { + let mut c: c_int; loop { c = getopt(argc as i32, argv.cast_const(), b"C:hdwS:\0".as_ptr().cast()); if c == -1 { @@ -445,10 +444,10 @@ impl swayidle_state { *config_path = Some(read_str(optarg).into()); } b'd' => { - swayidle_log_init(LOG_DEBUG); + swayidle_log_init(LevelFilter::Debug); } b'w' => { - self.wait = 1 != 0; + self.wait = true; } b'S' => { self.seat_name = read_str2(optarg); @@ -465,6 +464,7 @@ impl swayidle_state { _ => return 1, } } + swayidle_log_init(LevelFilter::Error); let args = (optind as usize..argc) .map(|i| read_str(*argv.add(i)).into_owned()) .collect::>(); @@ -503,14 +503,14 @@ impl swayidle_state { } 0 } - unsafe fn prepare_for_sleep(&self, msg: *mut sd_bus_message) -> libc::c_int { + unsafe fn prepare_for_sleep(&self, msg: *mut sd_bus_message) -> c_int { let mut going_down = 1; let ret = sd_bus_message_read(msg, b"b\0".as_ptr().cast(), ptr::addr_of_mut!(going_down)); if ret < 0 { - *__errno_location() = -ret; + Errno::set_raw(-ret); log::error!( "Failed to parse D-Bus response for Inhibit: {}", - strerror(*__errno_location()) + Errno::last().desc() ); } log::debug!("PrepareForSleep signal received {}", going_down); @@ -535,7 +535,7 @@ impl swayidle_state { release_inhibitor_lock(sleep_lock_fd); 0 } - unsafe fn handle_lock(&self) -> libc::c_int { + unsafe fn handle_lock(&self) -> c_int { log::debug!("Lock signal received"); if let Some(logind_lock_cmd) = &self.logind_lock_cmd { self.cmd_exec(logind_lock_cmd); @@ -543,7 +543,7 @@ impl swayidle_state { log::debug!("Lock command done"); 0 } - unsafe fn handle_unlock(&self) -> libc::c_int { + unsafe fn handle_unlock(&self) -> c_int { log::debug!("Unlock signal received"); if self.logind_idlehint { set_idle_hint(false); @@ -558,7 +558,7 @@ impl swayidle_state { &mut self, registry: *mut wl_registry, name: u32, - interface: *const libc::c_char, + interface: *const c_char, ) { if strcmp(interface, ext_idle_notifier_v1_interface.name) == 0 { idle_notifier = wl_registry_bind( @@ -569,7 +569,7 @@ impl swayidle_state { ) .cast(); } else if strcmp(interface, wl_seat_interface.name) == 0 { - let s: *mut seat = calloc(1, mem::size_of::()).cast(); + let s: *mut seat = Box::into_raw(Box::new(seat::new())); (*s).proxy = wl_registry_bind(registry, name, &wl_seat_interface, 2).cast(); wl_seat_add_listener((*s).proxy, ptr::addr_of!(wl_seat_listener), s.cast()); wl_list_insert(&mut self.seats, &mut (*s).link); @@ -613,7 +613,7 @@ impl swayidle_state { log::error!( "Too few parameters to timeout command. Usage: timeout " ); - exit(-1); + process::exit(-1); } let cmd = build_timeout_cmd(args); log::debug!("Register idle timeout at {} ms", (*cmd).timeout,); @@ -634,7 +634,7 @@ impl swayidle_state { log::error!( "Too few parameters to before-sleep command. Usage: before-sleep " ); - exit(-1); + process::exit(-1); } self.before_sleep_cmd = parse_command(&args[1..]); if let Some(before_sleep_cmd) = &self.before_sleep_cmd { @@ -647,7 +647,7 @@ impl swayidle_state { log::error!( "Too few parameters to after-resume command. Usage: after-resume " ); - exit(-1); + process::exit(-1); } self.after_resume_cmd = parse_command(&args[1..]); if let Some(after_resume_cmd) = &self.after_resume_cmd { @@ -658,7 +658,7 @@ impl swayidle_state { unsafe fn parse_lock(&mut self, args: &[String]) -> usize { if args.len() < 2 { log::error!("Too few parameters to lock command. Usage: lock "); - exit(-1); + process::exit(-1); } self.logind_lock_cmd = parse_command(&args[1..]); if let Some(logind_lock_cmd) = &self.logind_lock_cmd { @@ -669,7 +669,7 @@ impl swayidle_state { unsafe fn parse_unlock(&mut self, args: &[String]) -> usize { if args.len() < 2 { log::error!("Too few parameters to unlock command. Usage: unlock "); - exit(-1); + process::exit(-1); } self.logind_unlock_cmd = parse_command(&args[1..]); if let Some(logind_unlock_cmd) = &self.logind_unlock_cmd { @@ -680,11 +680,11 @@ impl swayidle_state { unsafe fn parse_idlehint(&mut self, args: &[String]) -> usize { if self.logind_idlehint { log::error!("Cannot add multiple idlehint events"); - exit(-1); + process::exit(-1); } if args.len() < 2 { log::error!("Too few parameters to idlehint command. Usage: idlehint "); - exit(-1); + process::exit(-1); } let cmd: *mut swayidle_timeout_cmd = build_timeout_cmd(args); (*cmd).idlehint = true; @@ -742,40 +742,31 @@ impl Drop for swayidle_state { unsafe { self.finish() } } } -unsafe fn read_str2(ptr: *const libc::c_char) -> Option { +unsafe fn read_str2(ptr: *const c_char) -> Option { if ptr.is_null() { None } else { Some(CStr::from_ptr(ptr).to_string_lossy().into()) } } -unsafe fn read_str(ptr: *const libc::c_char) -> Cow<'static, str> { +unsafe fn read_str(ptr: *const c_char) -> Cow<'static, str> { if ptr.is_null() { "".into() } else { CStr::from_ptr(ptr).to_string_lossy() } } -static mut sleep_lock_fd: libc::c_int = -1; +static mut sleep_lock_fd: c_int = -1; static mut bus: *mut sd_bus = ptr::null_mut(); -static mut session_name: *mut libc::c_char = ptr::null_mut(); -unsafe fn acquire_inhibitor_lock( - type_0: *const libc::c_char, - mode: *const libc::c_char, - fd: *mut libc::c_int, -) { +static mut session_name: *mut c_char = ptr::null_mut(); +unsafe fn acquire_inhibitor_lock(type_0: *const c_char, mode: *const c_char, fd: *mut c_int) { let mut msg = ptr::null_mut(); let mut error = sd_bus_error { name: ptr::null(), message: ptr::null(), need_free: 0, }; - let mut why = [0; 35]; - sprintf( - why.as_mut_ptr(), - b"Swayidle is preventing %s\0".as_ptr().cast(), - type_0, - ); + let mut why = format!("Swayidle is preventing {}", read_str(type_0)); let mut ret = sd_bus_call_method( bus, b"org.freedesktop.login1\0".as_ptr().cast(), @@ -786,7 +777,7 @@ unsafe fn acquire_inhibitor_lock( ptr::addr_of_mut!(msg), b"ssss\0".as_ptr().cast(), type_0, - b"swayidle\0".as_ptr().cast::(), + b"swayidle\0".as_ptr().cast::(), why.as_mut_ptr(), mode, ); @@ -799,32 +790,36 @@ unsafe fn acquire_inhibitor_lock( } else { ret = sd_bus_message_read(msg, b"h\0".as_ptr().cast(), fd); if ret < 0 { - *__errno_location() = -ret; + Errno::set_raw(-ret); log::error!( "Failed to parse D-Bus response for {} inhibit: {}", read_str(type_0), - strerror(*__errno_location()), + Errno::last().desc() ); } else { - *fd = libc::fcntl(*fd, 1030, 3); - if *fd >= 0 { - log::debug!("Got {} lock: {}", read_str(type_0), *fd,); - } else { - log::error!( - "Failed to copy {} lock fd: {}", - read_str(type_0), - strerror(*__errno_location()), - ); + match nix::fcntl::fcntl(RawFd::from(*fd), FcntlArg::F_DUPFD_CLOEXEC(RawFd::from(3))) { + Ok(fd1) => { + *fd = fd1; + log::debug!("Got {} lock: {}", read_str(type_0), *fd); + } + Err(err) => { + *fd = -(err as i32); + log::error!( + "Failed to copy {} lock fd: {}", + read_str(type_0), + Errno::last().desc() + ); + } } } } sd_bus_error_free(&mut error); sd_bus_message_unref(msg); } -unsafe fn release_inhibitor_lock(fd: libc::c_int) { +unsafe fn release_inhibitor_lock(fd: c_int) { if fd >= 0 { log::debug!("Releasing inhibitor lock {}", fd); - close(fd); + let _ = nix::unistd::close(fd); } } unsafe fn set_idle_hint(hint: bool) { @@ -856,7 +851,7 @@ unsafe fn set_idle_hint(hint: bool) { sd_bus_message_unref(msg); } unsafe fn get_logind_idle_inhibit() -> bool { - let mut locks: *const libc::c_char = ptr::null(); + let mut locks: *const c_char = ptr::null(); let res: bool; let mut reply = ptr::null_mut(); let mut ret = sd_bus_get_property( @@ -870,8 +865,7 @@ unsafe fn get_logind_idle_inhibit() -> bool { b"s\0".as_ptr().cast(), ); if ret >= 0 { - ret = - sd_bus_message_read_basic(reply, b's' as libc::c_char, ptr::addr_of_mut!(locks).cast()); + ret = sd_bus_message_read_basic(reply, b's' as c_char, ptr::addr_of_mut!(locks).cast()); if ret >= 0 { res = !strstr(locks, b"idle\0".as_ptr().cast()).is_null(); sd_bus_message_unref(reply); @@ -879,68 +873,55 @@ unsafe fn get_logind_idle_inhibit() -> bool { } } sd_bus_message_unref(reply); - *__errno_location() = -ret; + Errno::set_raw(-ret); log::error!( "Failed to parse get BlockInhibited property: {}", - strerror(*__errno_location()) + Errno::last().desc() ); false } unsafe extern "C" fn prepare_for_sleep( msg: *mut sd_bus_message, - _userdata: *mut libc::c_void, + _userdata: *mut c_void, _ret_error: *mut sd_bus_error, -) -> libc::c_int { +) -> c_int { state.prepare_for_sleep(msg) } unsafe extern "C" fn handle_lock( _msg: *mut sd_bus_message, - _userdata: *mut libc::c_void, + _userdata: *mut c_void, _ret_error: *mut sd_bus_error, -) -> libc::c_int { +) -> c_int { state.handle_lock() } unsafe extern "C" fn handle_unlock( _msg: *mut sd_bus_message, - _userdata: *mut libc::c_void, + _userdata: *mut c_void, _ret_error: *mut sd_bus_error, -) -> libc::c_int { +) -> c_int { state.handle_unlock() } -fn strerror(errno: i32) -> Cow<'static, str> { - let p = unsafe { libc::strerror(errno) }; - if p.is_null() { - "".into() - } else { - unsafe { CStr::from_ptr(p) }.to_string_lossy() - } -} unsafe extern "C" fn handle_property_changed( msg: *mut sd_bus_message, - _userdata: *mut libc::c_void, + _userdata: *mut c_void, _ret_error: *mut sd_bus_error, -) -> libc::c_int { +) -> c_int { let mut is_error = false; - let mut name: *const libc::c_char = ptr::null(); + let mut name: *const c_char = ptr::null(); log::debug!("PropertiesChanged signal received"); - let mut ret = - sd_bus_message_read_basic(msg, b's' as libc::c_char, ptr::addr_of_mut!(name).cast()); + let mut ret = sd_bus_message_read_basic(msg, b's' as c_char, ptr::addr_of_mut!(name).cast()); if ret >= 0 { if strcmp(name, b"org.freedesktop.login1.Manager\0".as_ptr().cast()) == 0 { log::debug!("Got PropertyChanged: {}", read_str(name)); - ret = sd_bus_message_enter_container( - msg, - b'a' as libc::c_char, - b"{sv}\0".as_ptr().cast(), - ); + ret = sd_bus_message_enter_container(msg, b'a' as c_char, b"{sv}\0".as_ptr().cast()); if ret < 0 { is_error = true; } else { - let mut prop: *const libc::c_char = ptr::null(); + let mut prop: *const c_char = ptr::null(); loop { ret = sd_bus_message_enter_container( msg, - b'e' as libc::c_char, + b'e' as c_char, b"sv\0".as_ptr().cast(), ); if ret <= 0 { @@ -948,7 +929,7 @@ unsafe extern "C" fn handle_property_changed( } ret = sd_bus_message_read_basic( msg, - b's' as libc::c_char, + b's' as c_char, ptr::addr_of_mut!(prop).cast(), ); if ret < 0 { @@ -982,18 +963,14 @@ unsafe extern "C" fn handle_property_changed( return 0; } } - *__errno_location() = -ret; + Errno::set_raw(-ret); log::error!( "Failed to parse D-Bus response for PropertyChanged: {}", - strerror(*__errno_location()) + Errno::last().desc() ); 0 } -unsafe extern "C" fn dbus_event( - _fd: libc::c_int, - mask: u32, - data: *mut libc::c_void, -) -> libc::c_int { +unsafe extern "C" fn dbus_event(_fd: c_int, mask: u32, data: *mut c_void) -> c_int { let bus_0 = data.cast(); if mask & WL_EVENT_HANGUP != 0 || mask & WL_EVENT_ERROR != 0 { state.sway_terminate(0); @@ -1010,10 +987,7 @@ unsafe extern "C" fn dbus_event( sd_bus_flush(bus_0); } if count < 0 { - log::error!( - "sd_bus_process failed, exiting: {}", - strerror(*__errno_location()) - ); + log::error!("sd_bus_process failed, exiting: {}", Errno::last().desc()); state.sway_terminate(0); } count @@ -1036,7 +1010,7 @@ unsafe fn set_session() { ptr::addr_of_mut!(error), ptr::addr_of_mut!(msg), b"s\0".as_ptr().cast(), - b"auto\0".as_ptr().cast::(), + b"auto\0".as_ptr().cast::(), ); if ret < 0 { log::debug!("GetSession failed: {}", read_str(error.message)); @@ -1051,7 +1025,7 @@ unsafe fn set_session() { ptr::addr_of_mut!(error), ptr::addr_of_mut!(msg), b"u\0".as_ptr().cast(), - getpid(), + Pid::this(), ); if ret < 0 { log::debug!("GetSessionByPID failed: {}", read_str(error.message)); @@ -1068,8 +1042,7 @@ unsafe fn set_session() { if ret < 0 { log::error!("Failed to read session name"); } else { - session_name = strdup(session_name_tmp); - log::debug!("Using session: {}", read_str(session_name)); + log::debug!("Using session: {}", read_str(session_name_tmp)); } } sd_bus_error_free(&mut error); @@ -1087,10 +1060,10 @@ unsafe fn setup_sleep_listener() { ptr::null_mut(), ); if ret < 0 { - *__errno_location() = -ret; + Errno::set_raw(-ret); log::error!( "Failed to add D-Bus signal match : sleep: {}", - strerror(*__errno_location()) + Errno::last().desc() ); return; } @@ -1112,10 +1085,10 @@ unsafe fn setup_lock_listener() { ptr::null_mut(), ); if ret < 0 { - *__errno_location() = -ret; + Errno::set_raw(-ret); log::error!( "Failed to add D-Bus signal match : lock: {}", - strerror(*__errno_location()) + Errno::last().desc() ); } } @@ -1131,10 +1104,10 @@ unsafe fn setup_unlock_listener() { ptr::null_mut(), ); if ret < 0 { - *__errno_location() = -ret; + Errno::set_raw(-ret); log::error!( "Failed to add D-Bus signal match : unlock: {}", - strerror(*__errno_location()) + Errno::last().desc() ); } } @@ -1150,15 +1123,15 @@ unsafe fn setup_property_changed_listener() { ptr::null_mut(), ); if ret < 0 { - *__errno_location() = -ret; + Errno::set_raw(-ret); log::error!( "Failed to add D-Bus signal match : property changed: {}", - strerror(*__errno_location()) + Errno::last().desc() ); } } unsafe extern "C" fn seat_handle_capabilities( - data: *mut libc::c_void, + data: *mut c_void, _seat_0: *mut wl_seat, capabilities: u32, ) { @@ -1166,28 +1139,28 @@ unsafe extern "C" fn seat_handle_capabilities( (*self_0).capabilities = capabilities; } unsafe extern "C" fn seat_handle_name( - data: *mut libc::c_void, + data: *mut c_void, _seat_0: *mut wl_seat, - name: *const libc::c_char, + name: *const c_char, ) { let self_0: *mut seat = data.cast(); - (*self_0).name = strdup(name); + (*self_0).name = read_str(name).into_owned(); } static mut wl_seat_listener: wl_seat_listener = wl_seat_listener { capabilities: Some(seat_handle_capabilities), name: Some(seat_handle_name), }; unsafe extern "C" fn handle_global( - _data: *mut libc::c_void, + _data: *mut c_void, registry: *mut wl_registry, name: u32, - interface: *const libc::c_char, + interface: *const c_char, _version: u32, ) { state.handle_global(registry, name, interface); } unsafe extern "C" fn handle_global_remove( - _data: *mut libc::c_void, + _data: *mut c_void, _registry: *mut wl_registry, _name: u32, ) { @@ -1202,7 +1175,7 @@ unsafe fn destroy_cmd_timer(cmd: *mut swayidle_timeout_cmd) { (*cmd).idle_notification = ptr::null_mut(); } } -unsafe fn register_timeout(cmd: *mut swayidle_timeout_cmd, timeout: libc::c_int) { +unsafe fn register_timeout(cmd: *mut swayidle_timeout_cmd, timeout: c_int) { destroy_cmd_timer(cmd); if timeout < 0 { log::debug!("Not registering idle timeout"); @@ -1218,7 +1191,7 @@ unsafe fn register_timeout(cmd: *mut swayidle_timeout_cmd, timeout: libc::c_int) ); (*cmd).registered_timeout = timeout; } -unsafe extern "C" fn handle_idled(data: *mut libc::c_void, _notif: *mut ext_idle_notification_v1) { +unsafe extern "C" fn handle_idled(data: *mut c_void, _notif: *mut ext_idle_notification_v1) { let cmd: *mut swayidle_timeout_cmd = data.cast(); (*cmd).resume_pending = true; log::debug!("idle state"); @@ -1228,10 +1201,7 @@ unsafe extern "C" fn handle_idled(data: *mut libc::c_void, _notif: *mut ext_idle state.cmd_exec(idle_cmd); } } -unsafe extern "C" fn handle_resumed( - data: *mut libc::c_void, - _notif: *mut ext_idle_notification_v1, -) { +unsafe extern "C" fn handle_resumed(data: *mut c_void, _notif: *mut ext_idle_notification_v1) { let cmd: *mut swayidle_timeout_cmd = data.cast(); (*cmd).resume_pending = false; log::debug!("active state"); @@ -1258,14 +1228,14 @@ unsafe fn parse_command(args: &[String]) -> Option { Some(ret.clone()) } unsafe fn build_timeout_cmd(args: &[String]) -> *mut swayidle_timeout_cmd { - *__errno_location() = 0; + Errno::set_raw(0); let Ok(seconds) = args[1].parse::() else { log::error!( "Invalid {} parameter '{}', it should be a numeric value representing seconds", args[0], args[1], ); - exit(-1); + process::exit(-1); }; Box::into_raw(Box::new(swayidle_timeout_cmd { idlehint: false, @@ -1281,14 +1251,10 @@ unsafe fn build_timeout_cmd(args: &[String]) -> *mut swayidle_timeout_cmd { resume_cmd: None, })) } -unsafe extern "C" fn handle_signal(sig: libc::c_int, _data: *mut libc::c_void) -> libc::c_int { +unsafe extern "C" fn handle_signal(sig: c_int, _data: *mut c_void) -> c_int { state.handle_signal(sig) } -unsafe extern "C" fn display_event( - _fd: libc::c_int, - mask: u32, - _data: *mut libc::c_void, -) -> libc::c_int { +unsafe extern "C" fn display_event(_fd: c_int, mask: u32, _data: *mut c_void) -> c_int { state.display_event(mask) } unsafe fn get_config_path() -> Option { @@ -1297,16 +1263,12 @@ unsafe fn get_config_path() -> Option { "$HOME/.swayidle/config", "/usr/local/etc/swayidle/config", ]; - let config_home = getenv(b"XDG_CONFIG_HOME\0".as_ptr().cast::()); - if config_home.is_null() || *config_home as u8 == b'\n' { + if matches!(env::var("XDG_CONFIG_HOME"), Ok(x) if !x.starts_with('\n')) { config_paths[0] = "$HOME/.config/swayidle/config"; } let mut path; let mut i = 0; - while i - < (mem::size_of::<[*mut libc::c_char; 3]>()) - .wrapping_div(mem::size_of::<*mut libc::c_char>()) - { + while i < (mem::size_of::<[*mut c_char; 3]>()).wrapping_div(mem::size_of::<*mut c_char>()) { if let Ok(res) = expand::wordexp(config_paths[i]) { path = &res[0]; if !path.is_empty() && nix::unistd::access(path.as_str(), AccessFlags::R_OK).is_ok() { @@ -1317,7 +1279,7 @@ unsafe fn get_config_path() -> Option { } None } -unsafe fn main_0(argc: usize, argv: *mut *mut libc::c_char) -> libc::c_int { +unsafe fn main_0(argc: usize, argv: *mut *mut c_char) -> c_int { state.init(); let mut config_path = None; if state.parse_args(argc, argv, &mut config_path) != 0 { @@ -1326,16 +1288,14 @@ unsafe fn main_0(argc: usize, argv: *mut *mut libc::c_char) -> libc::c_int { if config_path.is_none() { config_path = get_config_path(); } - let config_load = if let Some(ref config_path) = config_path { - state.load_config(Path::new(&config_path)) - } else { - -2 - }; + let config_load = config_path + .as_ref() + .map_or(-2, |config_path| state.load_config(Path::new(&config_path))); if config_load == -2 { log::debug!("No config file found."); } else if config_load == -22 { log::error!("Config file {} has errors, exiting.", config_path.unwrap()); - exit(-1); + process::exit(-1); } else { log::debug!("Loaded config at {}", config_path.unwrap()); } @@ -1359,7 +1319,7 @@ unsafe fn main_0(argc: usize, argv: *mut *mut libc::c_char) -> libc::c_int { let mut seat_i: *mut seat; seat_i = state.seats.next.cast(); while ptr::addr_of_mut!((*seat_i).link) != ptr::addr_of_mut!(state.seats) { - if !matches!(&state.seat_name, Some(seat_name) if read_str((*seat_i).name) != *seat_name) { + if !matches!(&state.seat_name, Some(seat_name) if (*seat_i).name != *seat_name) { seat = (*seat_i).proxy; } seat_i = (*seat_i).link.next.cast();