convert commands into strings
This commit is contained in:
parent
847bcd44d9
commit
30e7205ebf
151
src/main.rs
151
src/main.rs
|
@ -4,15 +4,23 @@
|
|||
non_upper_case_globals,
|
||||
clippy::missing_safety_doc
|
||||
)]
|
||||
use std::{borrow::Cow, env, ffi::CStr, mem, mem::MaybeUninit, os::raw::c_void, process, ptr};
|
||||
use std::{
|
||||
borrow::Cow,
|
||||
env,
|
||||
ffi::{CStr, CString},
|
||||
mem,
|
||||
mem::MaybeUninit,
|
||||
os::raw::c_void,
|
||||
process, ptr,
|
||||
};
|
||||
|
||||
use ext_idle_notify_v1_protocol::{
|
||||
ext_idle_notification_v1_interface, ext_idle_notifier_v1_interface,
|
||||
};
|
||||
use libc::{
|
||||
__errno_location, abort, access, calloc, close, execvp, exit, fclose, fopen, fork, free,
|
||||
getenv, getline, getopt, getpid, memset, printf, sigemptyset, signal, sigprocmask, sigset_t,
|
||||
size_t, sprintf, strcmp, strdup, strlen, strncmp, strstr, strtoul, waitpid,
|
||||
getenv, getline, getopt, getpid, printf, sigemptyset, signal, sigprocmask, sigset_t, size_t,
|
||||
sprintf, strcmp, strdup, strlen, strncmp, strstr, strtoul, waitpid,
|
||||
};
|
||||
use libsystemd_sys::bus::{
|
||||
sd_bus, sd_bus_call_method, sd_bus_default_system, sd_bus_error, sd_bus_error_free,
|
||||
|
@ -134,11 +142,11 @@ struct swayidle_state {
|
|||
event_loop: *mut wl_event_loop,
|
||||
timeout_cmds: wl_list,
|
||||
seats: wl_list,
|
||||
seat_name: *mut libc::c_char,
|
||||
before_sleep_cmd: *mut libc::c_char,
|
||||
after_resume_cmd: *mut libc::c_char,
|
||||
logind_lock_cmd: *mut libc::c_char,
|
||||
logind_unlock_cmd: *mut libc::c_char,
|
||||
seat_name: Option<String>,
|
||||
before_sleep_cmd: Option<String>,
|
||||
after_resume_cmd: Option<String>,
|
||||
logind_lock_cmd: Option<String>,
|
||||
logind_unlock_cmd: Option<String>,
|
||||
logind_idlehint: bool,
|
||||
timeouts_enabled: bool,
|
||||
wait: bool,
|
||||
|
@ -149,8 +157,8 @@ struct swayidle_timeout_cmd {
|
|||
timeout: libc::c_int,
|
||||
registered_timeout: libc::c_int,
|
||||
idle_notification: *mut ext_idle_notification_v1,
|
||||
idle_cmd: *mut libc::c_char,
|
||||
resume_cmd: *mut libc::c_char,
|
||||
idle_cmd: Option<String>,
|
||||
resume_cmd: Option<String>,
|
||||
idlehint: bool,
|
||||
resume_pending: bool,
|
||||
}
|
||||
|
@ -265,11 +273,11 @@ static mut state: swayidle_state = swayidle_state {
|
|||
prev: ptr::null_mut(),
|
||||
next: ptr::null_mut(),
|
||||
},
|
||||
seat_name: ptr::null_mut(),
|
||||
before_sleep_cmd: ptr::null_mut(),
|
||||
after_resume_cmd: ptr::null_mut(),
|
||||
logind_lock_cmd: ptr::null_mut(),
|
||||
logind_unlock_cmd: ptr::null_mut(),
|
||||
seat_name: None,
|
||||
before_sleep_cmd: None,
|
||||
after_resume_cmd: None,
|
||||
logind_lock_cmd: None,
|
||||
logind_unlock_cmd: None,
|
||||
logind_idlehint: false,
|
||||
timeouts_enabled: false,
|
||||
wait: false,
|
||||
|
@ -290,7 +298,6 @@ unsafe extern "C" fn swayidle_log_init(verbosity: log_importance) {
|
|||
}
|
||||
impl swayidle_state {
|
||||
unsafe fn init(&mut self) {
|
||||
memset(ptr::addr_of_mut!(*self).cast(), 0, mem::size_of::<Self>());
|
||||
wl_list_init(&mut self.timeout_cmds);
|
||||
wl_list_init(&mut self.seats);
|
||||
}
|
||||
|
@ -299,22 +306,18 @@ impl swayidle_state {
|
|||
let mut tmp: *mut swayidle_timeout_cmd = (*cmd).link.next.cast();
|
||||
while ptr::addr_of_mut!((*cmd).link) != ptr::addr_of_mut!(self.timeout_cmds) {
|
||||
wl_list_remove(&mut (*cmd).link);
|
||||
free((*cmd).idle_cmd.cast());
|
||||
free((*cmd).resume_cmd.cast());
|
||||
free(cmd.cast());
|
||||
drop(Box::from_raw(cmd));
|
||||
cmd = tmp;
|
||||
tmp = (*cmd).link.next.cast();
|
||||
}
|
||||
free(self.after_resume_cmd.cast());
|
||||
free(self.before_sleep_cmd.cast());
|
||||
}
|
||||
unsafe fn sway_terminate(&self, exit_code: libc::c_int) -> ! {
|
||||
wl_display_disconnect(self.display);
|
||||
wl_event_loop_destroy(self.event_loop);
|
||||
exit(exit_code);
|
||||
}
|
||||
unsafe fn cmd_exec(&self, param: *mut libc::c_char) {
|
||||
log::debug!("Cmd exec {}", read_str(param));
|
||||
unsafe fn cmd_exec(&self, param: &str) {
|
||||
log::debug!("Cmd exec {param}");
|
||||
let mut pid = fork();
|
||||
match pid {
|
||||
0 => {
|
||||
|
@ -330,10 +333,11 @@ impl swayidle_state {
|
|||
signal(2, 0);
|
||||
signal(15, 0);
|
||||
signal(10, 0);
|
||||
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,
|
||||
param.as_ptr(),
|
||||
ptr::null(),
|
||||
];
|
||||
execvp(cmd[0], cmd.as_ptr());
|
||||
|
@ -352,7 +356,7 @@ impl swayidle_state {
|
|||
log::error!("fork failed: {}", strerror(*__errno_location()),);
|
||||
}
|
||||
_ => {
|
||||
log::debug!("Spawned process {}", read_str(param));
|
||||
log::debug!("Spawned process {param}");
|
||||
if self.wait {
|
||||
log::debug!("Blocking until process exits");
|
||||
}
|
||||
|
@ -460,7 +464,7 @@ impl swayidle_state {
|
|||
self.wait = 1 != 0;
|
||||
}
|
||||
83 => {
|
||||
self.seat_name = strdup(optarg);
|
||||
self.seat_name = read_str2(optarg);
|
||||
}
|
||||
104 | 63 => {
|
||||
printf(b"Usage: %s [OPTIONS]\n\0".as_ptr().cast(), *argv);
|
||||
|
@ -518,16 +522,16 @@ impl swayidle_state {
|
|||
b"delay\0".as_ptr().cast(),
|
||||
ptr::addr_of_mut!(sleep_lock_fd),
|
||||
);
|
||||
if !self.after_resume_cmd.is_null() {
|
||||
self.cmd_exec(self.after_resume_cmd);
|
||||
if let Some(after_resume_cmd) = &self.after_resume_cmd {
|
||||
self.cmd_exec(after_resume_cmd);
|
||||
}
|
||||
if self.logind_idlehint {
|
||||
set_idle_hint(false);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
if !self.before_sleep_cmd.is_null() {
|
||||
self.cmd_exec(self.before_sleep_cmd);
|
||||
if let Some(before_sleep_cmd) = &self.before_sleep_cmd {
|
||||
self.cmd_exec(before_sleep_cmd);
|
||||
}
|
||||
log::debug!("Prepare for sleep done");
|
||||
release_inhibitor_lock(sleep_lock_fd);
|
||||
|
@ -535,8 +539,8 @@ impl swayidle_state {
|
|||
}
|
||||
unsafe fn handle_lock(&self) -> libc::c_int {
|
||||
log::debug!("Lock signal received");
|
||||
if !self.logind_lock_cmd.is_null() {
|
||||
self.cmd_exec(self.logind_lock_cmd);
|
||||
if let Some(logind_lock_cmd) = &self.logind_lock_cmd {
|
||||
self.cmd_exec(logind_lock_cmd);
|
||||
}
|
||||
log::debug!("Lock command done");
|
||||
0
|
||||
|
@ -546,8 +550,8 @@ impl swayidle_state {
|
|||
if self.logind_idlehint {
|
||||
set_idle_hint(false);
|
||||
}
|
||||
if !self.logind_unlock_cmd.is_null() {
|
||||
self.cmd_exec(self.logind_unlock_cmd);
|
||||
if let Some(logind_unlock_cmd) = &self.logind_unlock_cmd {
|
||||
self.cmd_exec(logind_unlock_cmd);
|
||||
}
|
||||
log::debug!("Unlock command done");
|
||||
0
|
||||
|
@ -635,8 +639,8 @@ impl swayidle_state {
|
|||
exit(-1);
|
||||
}
|
||||
self.before_sleep_cmd = parse_command(argc - 1, &mut *argv.offset(1));
|
||||
if !self.before_sleep_cmd.is_null() {
|
||||
log::debug!("Setup sleep lock: {}", read_str(self.before_sleep_cmd));
|
||||
if let Some(before_sleep_cmd) = &self.before_sleep_cmd {
|
||||
log::debug!("Setup sleep lock: {before_sleep_cmd}");
|
||||
}
|
||||
2
|
||||
}
|
||||
|
@ -648,8 +652,8 @@ impl swayidle_state {
|
|||
exit(-1);
|
||||
}
|
||||
self.after_resume_cmd = parse_command(argc - 1, &mut *argv.offset(1));
|
||||
if !self.after_resume_cmd.is_null() {
|
||||
log::debug!("Setup resume hook: {}", read_str(self.after_resume_cmd));
|
||||
if let Some(after_resume_cmd) = &self.after_resume_cmd {
|
||||
log::debug!("Setup resume hook: {after_resume_cmd}");
|
||||
}
|
||||
2
|
||||
}
|
||||
|
@ -659,8 +663,8 @@ impl swayidle_state {
|
|||
exit(-1);
|
||||
}
|
||||
self.logind_lock_cmd = parse_command(argc - 1, &mut *argv.offset(1));
|
||||
if !self.logind_lock_cmd.is_null() {
|
||||
log::debug!("Setup lock hook: {}", read_str(self.logind_lock_cmd));
|
||||
if let Some(logind_lock_cmd) = &self.logind_lock_cmd {
|
||||
log::debug!("Setup lock hook: {logind_lock_cmd}");
|
||||
}
|
||||
2
|
||||
}
|
||||
|
@ -670,8 +674,8 @@ impl swayidle_state {
|
|||
exit(-1);
|
||||
}
|
||||
self.logind_unlock_cmd = parse_command(argc - 1, &mut *argv.offset(1));
|
||||
if !self.logind_unlock_cmd.is_null() {
|
||||
log::debug!("Setup unlock hook: {}", read_str(self.logind_unlock_cmd));
|
||||
if let Some(logind_unlock_cmd) = &self.logind_unlock_cmd {
|
||||
log::debug!("Setup unlock hook: {logind_unlock_cmd}");
|
||||
}
|
||||
2
|
||||
}
|
||||
|
@ -752,6 +756,13 @@ impl Drop for swayidle_state {
|
|||
unsafe { self.finish() }
|
||||
}
|
||||
}
|
||||
unsafe fn read_str2(ptr: *const libc::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> {
|
||||
if ptr.is_null() {
|
||||
"".into()
|
||||
|
@ -1227,8 +1238,8 @@ unsafe extern "C" fn handle_idled(data: *mut libc::c_void, _notif: *mut ext_idle
|
|||
log::debug!("idle state");
|
||||
if (*cmd).idlehint {
|
||||
set_idle_hint(true);
|
||||
} else if !(*cmd).idle_cmd.is_null() {
|
||||
state.cmd_exec((*cmd).idle_cmd);
|
||||
} else if let Some(idle_cmd) = &(*cmd).idle_cmd {
|
||||
state.cmd_exec(idle_cmd);
|
||||
}
|
||||
}
|
||||
unsafe extern "C" fn handle_resumed(
|
||||
|
@ -1243,8 +1254,8 @@ unsafe extern "C" fn handle_resumed(
|
|||
}
|
||||
if (*cmd).idlehint {
|
||||
set_idle_hint(false);
|
||||
} else if !(*cmd).resume_cmd.is_null() {
|
||||
state.cmd_exec((*cmd).resume_cmd);
|
||||
} else if let Some(resume_cmd) = &(*cmd).resume_cmd {
|
||||
state.cmd_exec(resume_cmd);
|
||||
}
|
||||
}
|
||||
static mut idle_notification_listener: ext_idle_notification_v1_listener =
|
||||
|
@ -1252,13 +1263,17 @@ static mut idle_notification_listener: ext_idle_notification_v1_listener =
|
|||
idled: Some(handle_idled),
|
||||
resumed: Some(handle_resumed),
|
||||
};
|
||||
unsafe extern "C" fn parse_command(argc: usize, argv: *mut *mut libc::c_char) -> *mut libc::c_char {
|
||||
unsafe fn parse_command(argc: usize, argv: *mut *mut libc::c_char) -> Option<String> {
|
||||
if argc < 1 {
|
||||
log::error!("Missing command");
|
||||
return ptr::null_mut();
|
||||
return None;
|
||||
}
|
||||
log::debug!("Command: {}", read_str(*argv));
|
||||
strdup(*argv)
|
||||
let Some(ret) = read_str2(*argv) else {
|
||||
log::error!("Missing command");
|
||||
return None;
|
||||
};
|
||||
log::debug!("Command: {ret}");
|
||||
Some(ret)
|
||||
}
|
||||
unsafe extern "C" fn build_timeout_cmd(argv: *mut *mut libc::c_char) -> *mut swayidle_timeout_cmd {
|
||||
*__errno_location() = 0;
|
||||
|
@ -1272,15 +1287,19 @@ unsafe extern "C" fn build_timeout_cmd(argv: *mut *mut libc::c_char) -> *mut swa
|
|||
);
|
||||
exit(-1);
|
||||
}
|
||||
let cmd: *mut swayidle_timeout_cmd = calloc(1, mem::size_of::<swayidle_timeout_cmd>()).cast();
|
||||
(*cmd).idlehint = false;
|
||||
(*cmd).resume_pending = false;
|
||||
if seconds > 0 {
|
||||
(*cmd).timeout = seconds * 1000;
|
||||
} else {
|
||||
(*cmd).timeout = -1;
|
||||
}
|
||||
cmd
|
||||
Box::into_raw(Box::new(swayidle_timeout_cmd {
|
||||
idlehint: false,
|
||||
resume_pending: false,
|
||||
timeout: if seconds > 0 { seconds * 1000 } else { -1 },
|
||||
idle_cmd: None,
|
||||
idle_notification: ptr::null_mut(),
|
||||
link: wl_list {
|
||||
prev: ptr::null_mut(),
|
||||
next: ptr::null_mut(),
|
||||
},
|
||||
registered_timeout: 0,
|
||||
resume_cmd: None,
|
||||
}))
|
||||
}
|
||||
unsafe extern "C" fn handle_signal(sig: libc::c_int, _data: *mut libc::c_void) -> libc::c_int {
|
||||
state.handle_signal(sig)
|
||||
|
@ -1375,7 +1394,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 (state.seat_name).is_null() || strcmp((*seat_i).name, state.seat_name) == 0 {
|
||||
if !matches!(&state.seat_name, Some(seat_name) if read_str((*seat_i).name) != *seat_name) {
|
||||
seat = (*seat_i).proxy;
|
||||
}
|
||||
seat_i = (*seat_i).link.next.cast();
|
||||
|
@ -1385,25 +1404,25 @@ unsafe fn main_0(argc: usize, argv: *mut *mut libc::c_char) -> libc::c_int {
|
|||
return -4;
|
||||
}
|
||||
if seat.is_null() {
|
||||
if state.seat_name.is_null() {
|
||||
log::error!("No seat found");
|
||||
if let Some(seat_name) = &state.seat_name {
|
||||
log::error!("Seat {seat_name} not found");
|
||||
} else {
|
||||
log::error!("Seat {} not found", read_str(state.seat_name));
|
||||
log::error!("No seat found");
|
||||
}
|
||||
return -5;
|
||||
}
|
||||
let mut should_run = wl_list_empty(&state.timeout_cmds) == 0;
|
||||
state.connect_to_bus();
|
||||
setup_property_changed_listener();
|
||||
if !state.before_sleep_cmd.is_null() || !state.after_resume_cmd.is_null() {
|
||||
if state.before_sleep_cmd.is_some() || state.after_resume_cmd.is_some() {
|
||||
should_run = true;
|
||||
setup_sleep_listener();
|
||||
}
|
||||
if !state.logind_lock_cmd.is_null() {
|
||||
if state.logind_lock_cmd.is_some() {
|
||||
should_run = true;
|
||||
setup_lock_listener();
|
||||
}
|
||||
if !state.logind_unlock_cmd.is_null() {
|
||||
if state.logind_unlock_cmd.is_some() {
|
||||
should_run = true;
|
||||
setup_unlock_listener();
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue