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"
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"] }

View file

@ -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<unsafe extern "C" fn(*mut libc::c_void, *mut wl_registry, u32) -> ()>,
global:
Option<unsafe extern "C" fn(*mut c_void, *mut wl_registry, u32, *const c_char, u32) -> ()>,
global_remove: Option<unsafe extern "C" fn(*mut c_void, *mut wl_registry, u32) -> ()>,
}
#[derive(Copy, Clone)]
#[repr(C)]
struct wl_seat_listener {
capabilities: Option<unsafe extern "C" fn(*mut libc::c_void, *mut wl_seat, u32) -> ()>,
name: Option<unsafe extern "C" fn(*mut libc::c_void, *mut wl_seat, *const libc::c_char) -> ()>,
capabilities: Option<unsafe extern "C" fn(*mut c_void, *mut wl_seat, u32) -> ()>,
name: Option<unsafe extern "C" fn(*mut c_void, *mut wl_seat, *const c_char) -> ()>,
}
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<unsafe extern "C" fn(*mut libc::c_void, *mut ext_idle_notification_v1) -> ()>,
resumed: 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 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)]
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<String>,
resume_cmd: Option<String>,
@ -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::<sigset_t>::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"),
&param,
];
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<String>,
) -> 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::<Vec<_>>();
@ -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::<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();
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 <seconds> <command>"
);
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 <command>"
);
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 <command>"
);
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 <command>");
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 <command>");
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 <seconds>");
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<String> {
unsafe fn read_str2(ptr: *const c_char) -> Option<String> {
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::<libc::c_char>(),
b"swayidle\0".as_ptr().cast::<c_char>(),
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::<libc::c_char>(),
b"auto\0".as_ptr().cast::<c_char>(),
);
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<String> {
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::<i32>() 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<String> {
@ -1297,16 +1263,12 @@ unsafe fn get_config_path() -> Option<String> {
"$HOME/.swayidle/config",
"/usr/local/etc/swayidle/config",
];
let config_home = getenv(b"XDG_CONFIG_HOME\0".as_ptr().cast::<libc::c_char>());
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<String> {
}
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();