nuke most of libc crate usage

This commit is contained in:
chayleaf 2024-08-14 20:35:42 +07:00
parent aac6c64779
commit 968c55fc20
Signed by: chayleaf
GPG key ID: 78171AD46227E68E
2 changed files with 201 additions and 241 deletions

View file

@ -13,6 +13,6 @@ itertools = "0.13.0"
libc = "0.2.155" libc = "0.2.155"
libsystemd-sys = "0.9.3" libsystemd-sys = "0.9.3"
log = "0.4.22" 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-client = { version = "0.31.5", features = ["log"] }
wayland-sys = { version = "0.31.4", features = ["client", "server"] } wayland-sys = { version = "0.31.4", features = ["client", "server"] }

View file

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