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