nuke most of libc crate usage
This commit is contained in:
parent
aac6c64779
commit
968c55fc20
|
@ -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"] }
|
||||
|
|
432
src/main.rs
432
src/main.rs
|
@ -7,11 +7,11 @@
|
|||
use std::{
|
||||
borrow::Cow,
|
||||
env,
|
||||
ffi::{CStr, CString},
|
||||
ffi::{c_char, c_int, c_void, CStr, CString},
|
||||
fs::File,
|
||||
io::{BufRead, BufReader},
|
||||
mem::{self, MaybeUninit},
|
||||
os::raw::c_void,
|
||||
mem,
|
||||
os::fd::RawFd,
|
||||
path::Path,
|
||||
process, ptr,
|
||||
};
|
||||
|
@ -19,10 +19,7 @@ use std::{
|
|||
use ext_idle_notify_v1_protocol::{
|
||||
ext_idle_notification_v1_interface, ext_idle_notifier_v1_interface,
|
||||
};
|
||||
use libc::{
|
||||
__errno_location, abort, calloc, close, execvp, exit, fork, getenv, getopt, getpid,
|
||||
sigemptyset, signal, sigprocmask, sigset_t, size_t, sprintf, strcmp, strdup, strstr, waitpid,
|
||||
};
|
||||
use libc::{getopt, size_t, strcmp, strstr};
|
||||
use libsystemd_sys::bus::{
|
||||
sd_bus, sd_bus_call_method, sd_bus_default_system, sd_bus_error, sd_bus_error_free,
|
||||
sd_bus_flush, sd_bus_get_fd, sd_bus_get_property, sd_bus_message,
|
||||
|
@ -30,7 +27,16 @@ use libsystemd_sys::bus::{
|
|||
sd_bus_message_read, sd_bus_message_read_basic, sd_bus_message_skip, sd_bus_message_unref,
|
||||
sd_bus_process, sd_bus_slot,
|
||||
};
|
||||
use nix::unistd::AccessFlags;
|
||||
use log::LevelFilter;
|
||||
use nix::{
|
||||
errno::Errno,
|
||||
fcntl::FcntlArg,
|
||||
sys::{
|
||||
signal::{SigHandler, SigSet, SigmaskHow, Signal},
|
||||
wait::WaitStatus,
|
||||
},
|
||||
unistd::{AccessFlags, ForkResult, Pid},
|
||||
};
|
||||
use wayland_client::protocol::__interfaces::{wl_registry_interface, wl_seat_interface};
|
||||
use wayland_sys::{
|
||||
client::{
|
||||
|
@ -69,8 +75,8 @@ type ext_idle_notifier_v1 = wl_interface;
|
|||
unused_mut
|
||||
)]
|
||||
extern "C" {
|
||||
static mut optind: libc::c_int;
|
||||
static mut optarg: *mut libc::c_char;
|
||||
static mut optind: c_int;
|
||||
static mut optarg: *mut c_char;
|
||||
fn wl_proxy_marshal_flags(
|
||||
proxy: *mut wl_proxy,
|
||||
opcode: u32,
|
||||
|
@ -82,33 +88,26 @@ extern "C" {
|
|||
fn sd_bus_match_signal(
|
||||
bus_0: *mut sd_bus,
|
||||
ret: *mut *mut sd_bus_slot,
|
||||
sender: *const libc::c_char,
|
||||
path: *const libc::c_char,
|
||||
interface: *const libc::c_char,
|
||||
member: *const libc::c_char,
|
||||
sender: *const c_char,
|
||||
path: *const c_char,
|
||||
interface: *const c_char,
|
||||
member: *const c_char,
|
||||
callback: sd_bus_message_handler_t,
|
||||
userdata: *mut libc::c_void,
|
||||
) -> libc::c_int;
|
||||
userdata: *mut c_void,
|
||||
) -> c_int;
|
||||
}
|
||||
#[derive(Copy, Clone)]
|
||||
#[repr(C)]
|
||||
struct wl_registry_listener {
|
||||
global: Option<
|
||||
unsafe extern "C" fn(
|
||||
*mut libc::c_void,
|
||||
*mut wl_registry,
|
||||
u32,
|
||||
*const libc::c_char,
|
||||
u32,
|
||||
) -> (),
|
||||
>,
|
||||
global_remove: Option<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 nix::unistd::fork() {
|
||||
Ok(ForkResult::Child) => {
|
||||
let pid = if self.wait {
|
||||
Ok(ForkResult::Child)
|
||||
} else {
|
||||
nix::unistd::fork()
|
||||
};
|
||||
match pid {
|
||||
0 => {
|
||||
if !self.wait {
|
||||
pid = 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"),
|
||||
¶m,
|
||||
];
|
||||
execvp(cmd[0], cmd.as_ptr());
|
||||
log::error!("execve failed!: {}", strerror(*__errno_location()),);
|
||||
exit(1);
|
||||
let err = match nix::unistd::execvp(cmd[0], &cmd) {
|
||||
Err(err) => err,
|
||||
Ok(res) => match res {},
|
||||
};
|
||||
log::error!("execve failed!: {}", err.desc());
|
||||
process::exit(1);
|
||||
}
|
||||
pid if pid < 0 => {
|
||||
log::error!("fork failed: {}", strerror(*__errno_location()),);
|
||||
exit(1);
|
||||
Err(err) => {
|
||||
log::error!("fork failed: {}", err.desc());
|
||||
process::exit(1);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
exit(0);
|
||||
process::exit(0);
|
||||
}
|
||||
pid if pid < 0 => {
|
||||
log::error!("fork failed: {}", strerror(*__errno_location()),);
|
||||
Err(err) => {
|
||||
log::error!("fork failed: {}", err.desc());
|
||||
}
|
||||
_ => {
|
||||
Ok(ForkResult::Parent { child: pid }) => {
|
||||
log::debug!("Spawned process {param}");
|
||||
if self.wait {
|
||||
log::debug!("Blocking until process exits");
|
||||
}
|
||||
let mut status = 0;
|
||||
waitpid(pid, &mut status, 0);
|
||||
if i32::from(self.wait) != 0 && status & 0x7f == 0 {
|
||||
log::debug!("Process exit status: {}", (status & 0xff00) >> 8,);
|
||||
let status = nix::sys::wait::waitpid(pid, None);
|
||||
if self.wait {
|
||||
if let Ok(WaitStatus::Exited(_, status)) = status {
|
||||
log::debug!("Process exit status: {status}");
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -359,11 +361,8 @@ impl swayidle_state {
|
|||
unsafe fn connect_to_bus(&self) {
|
||||
let ret = sd_bus_default_system(ptr::addr_of_mut!(bus));
|
||||
if ret < 0 {
|
||||
*__errno_location() = -ret;
|
||||
log::error!(
|
||||
"Failed to open D-Bus connection: {}",
|
||||
strerror(*__errno_location()),
|
||||
);
|
||||
Errno::set_raw(-ret);
|
||||
log::error!("Failed to open D-Bus connection: {}", Errno::last().desc());
|
||||
return;
|
||||
}
|
||||
let source = wl_event_loop_add_fd(
|
||||
|
@ -376,7 +375,7 @@ impl swayidle_state {
|
|||
wl_event_source_check(source);
|
||||
set_session();
|
||||
}
|
||||
unsafe fn display_event(&self, mask: u32) -> libc::c_int {
|
||||
unsafe fn display_event(&self, mask: u32) -> c_int {
|
||||
if mask & WL_EVENT_HANGUP != 0 || mask & WL_EVENT_ERROR != 0 {
|
||||
self.sway_terminate(0);
|
||||
}
|
||||
|
@ -395,13 +394,13 @@ impl swayidle_state {
|
|||
if count < 0 {
|
||||
log::error!(
|
||||
"wl_display_dispatch failed, exiting: {}",
|
||||
strerror(*__errno_location()),
|
||||
Errno::last().desc()
|
||||
);
|
||||
self.sway_terminate(0);
|
||||
}
|
||||
count
|
||||
}
|
||||
unsafe fn handle_signal(&self, sig: libc::c_int) -> libc::c_int {
|
||||
unsafe fn handle_signal(&self, sig: c_int) -> c_int {
|
||||
let mut cmd: *mut swayidle_timeout_cmd;
|
||||
match sig {
|
||||
2 | 15 => {
|
||||
|
@ -426,15 +425,15 @@ impl swayidle_state {
|
|||
}
|
||||
_ => {}
|
||||
}
|
||||
abort();
|
||||
process::abort();
|
||||
}
|
||||
unsafe fn parse_args(
|
||||
&mut self,
|
||||
argc: usize,
|
||||
argv: *mut *mut libc::c_char,
|
||||
argv: *mut *mut c_char,
|
||||
config_path: &mut Option<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 {
|
||||
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),
|
||||
strerror(*__errno_location()),
|
||||
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();
|
||||
|
|
Loading…
Reference in a new issue