Support stable rust
This removes use of Option.contains(), and provides a fallback pidfd implementation for stable.
This commit is contained in:
parent
04650b3c53
commit
23fef4d9e3
1
Cargo.lock
generated
1
Cargo.lock
generated
@ -260,6 +260,7 @@ dependencies = [
|
|||||||
"bscreensaver-command",
|
"bscreensaver-command",
|
||||||
"bscreensaver-util",
|
"bscreensaver-util",
|
||||||
"clap",
|
"clap",
|
||||||
|
"libc",
|
||||||
"log",
|
"log",
|
||||||
"nix",
|
"nix",
|
||||||
"xcb",
|
"xcb",
|
||||||
|
17
Makefile
17
Makefile
@ -17,15 +17,22 @@ HELPERS = \
|
|||||||
|
|
||||||
INSTALL ?= install
|
INSTALL ?= install
|
||||||
|
|
||||||
|
RUST_RELEASE_CHANNEL = nightly
|
||||||
|
ifeq ($(RUST_RELEASE_CHANNEL),nightly)
|
||||||
|
RUST_RELEASE_CHANNEL_ARG = +nightly
|
||||||
|
else
|
||||||
|
FEATURES_ARGS = --no-default-features
|
||||||
|
endif
|
||||||
|
|
||||||
DEV_LOG_LEVEL = debug
|
DEV_LOG_LEVEL = debug
|
||||||
|
|
||||||
all: release
|
all: release
|
||||||
|
|
||||||
release:
|
release:
|
||||||
HELPER_DIR=$(HELPER_DIR) cargo build --release
|
HELPER_DIR=$(HELPER_DIR) cargo $(RUST_RELEASE_CHANNEL_ARG) build $(FEATURES_ARGS) --release
|
||||||
|
|
||||||
dev:
|
dev:
|
||||||
HELPER_DIR=target/debug cargo build
|
HELPER_DIR=target/debug cargo $(RUST_RELEASE_CHANNEL_ARG) build $(FEATURES_ARGS)
|
||||||
|
|
||||||
install: release
|
install: release
|
||||||
$(INSTALL) -m 0755 -d $(BINDIR) $(HELPER_DIR) $(CONFIG_DIR) $(APPLICATIONS_DIR)
|
$(INSTALL) -m 0755 -d $(BINDIR) $(HELPER_DIR) $(CONFIG_DIR) $(APPLICATIONS_DIR)
|
||||||
@ -35,7 +42,7 @@ install: release
|
|||||||
$(INSTALL) -m 0644 settings/bscreensaver-settings.desktop $(APPLICATIONS_DIR)
|
$(INSTALL) -m 0644 settings/bscreensaver-settings.desktop $(APPLICATIONS_DIR)
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
cargo clean
|
cargo $(RUST_RELEASE_CHANNEL_ARG) clean
|
||||||
|
|
||||||
uninstall:
|
uninstall:
|
||||||
rm -f $(BINDIR)/bscreensaver $(BINDIR)/bscreensaver-command $(BINDIR)/bscreensaver-settings $(addprefix $(HELPER_DIR)/,$(HELPERS)) || true
|
rm -f $(BINDIR)/bscreensaver $(BINDIR)/bscreensaver-command $(BINDIR)/bscreensaver-settings $(addprefix $(HELPER_DIR)/,$(HELPERS)) || true
|
||||||
@ -50,10 +57,10 @@ run: dev
|
|||||||
BSCREENSAVER_SYSTEMD_LOG=$(DEV_LOG_LEVEL) \
|
BSCREENSAVER_SYSTEMD_LOG=$(DEV_LOG_LEVEL) \
|
||||||
BSCREENSAVER_DIALOG_GTK3_LOG=$(DEV_LOG_LEVEL) \
|
BSCREENSAVER_DIALOG_GTK3_LOG=$(DEV_LOG_LEVEL) \
|
||||||
HELPER_DIR=target/debug \
|
HELPER_DIR=target/debug \
|
||||||
cargo run --bin bscreensaver
|
cargo $(RUST_RELEASE_CHANNEL_ARG) run $(FEATURES_ARGS) --bin bscreensaver
|
||||||
|
|
||||||
run-dialog:
|
run-dialog:
|
||||||
RUST_BACKTRACE=1 \
|
RUST_BACKTRACE=1 \
|
||||||
BSCREENSAVER_DIALOG_GTK3_LOG=$(DEV_LOG_LEVEL) \
|
BSCREENSAVER_DIALOG_GTK3_LOG=$(DEV_LOG_LEVEL) \
|
||||||
BSCREENSAVER_DIALOG_STANDALONE=1 \
|
BSCREENSAVER_DIALOG_STANDALONE=1 \
|
||||||
cargo run --bin bscreensaver-dialog-gtk3
|
cargo $(RUST_RELEASE_CHANNEL_ARG) run $(FEATURES_ARGS) --bin bscreensaver-dialog-gtk3
|
||||||
|
@ -1,6 +1,3 @@
|
|||||||
#![feature(option_result_contains)]
|
|
||||||
#![feature(is_some_with)]
|
|
||||||
|
|
||||||
use async_std::{fs::File, prelude::*, sync::{Arc, Mutex}, task};
|
use async_std::{fs::File, prelude::*, sync::{Arc, Mutex}, task};
|
||||||
use bscreensaver_util::init_logging;
|
use bscreensaver_util::init_logging;
|
||||||
use futures::{future::FutureExt, pin_mut, select};
|
use futures::{future::FutureExt, pin_mut, select};
|
||||||
@ -160,7 +157,7 @@ async fn dbus_task(state: Arc<Mutex<State>>) -> anyhow::Result<()> {
|
|||||||
let args = name_owner_changed.args()?;
|
let args = name_owner_changed.args()?;
|
||||||
match args.name() {
|
match args.name() {
|
||||||
BusName::WellKnown(name) if name == OUR_DBUS_NAME => {
|
BusName::WellKnown(name) if name == OUR_DBUS_NAME => {
|
||||||
if args.new_owner().is_none() || args.new_owner().is_some_and(|no| no != our_unique_name) {
|
if args.new_owner().is_none() || args.new_owner().as_ref().filter(|no| no != &our_unique_name).is_some() {
|
||||||
info!("Lost bus name {}; quitting", OUR_DBUS_NAME);
|
info!("Lost bus name {}; quitting", OUR_DBUS_NAME);
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
@ -168,7 +165,7 @@ async fn dbus_task(state: Arc<Mutex<State>>) -> anyhow::Result<()> {
|
|||||||
BusName::Unique(name) => {
|
BusName::Unique(name) => {
|
||||||
if args.new_owner().is_none() {
|
if args.new_owner().is_none() {
|
||||||
state.lock().await.inhibitors.retain(|inhibitor| {
|
state.lock().await.inhibitors.retain(|inhibitor| {
|
||||||
if inhibitor.peer.contains(name) {
|
if inhibitor.peer.as_ref().filter(|n| n == &name).is_some() {
|
||||||
info!("Canceling inhibit from {}, as the client has disappeared", inhibitor.app_name);
|
info!("Canceling inhibit from {}, as the client has disappeared", inhibitor.app_name);
|
||||||
false
|
false
|
||||||
} else {
|
} else {
|
||||||
|
@ -12,11 +12,16 @@ readme = "README.md"
|
|||||||
keywords = ["gui", "screensaver", "screen-locker"]
|
keywords = ["gui", "screensaver", "screen-locker"]
|
||||||
categories = ["gui"]
|
categories = ["gui"]
|
||||||
|
|
||||||
|
[features]
|
||||||
|
default = ["use-nightly"]
|
||||||
|
use-nightly = []
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
anyhow = "1"
|
anyhow = "1"
|
||||||
clap = "3"
|
clap = "3"
|
||||||
bscreensaver-command = { path = "../command" }
|
bscreensaver-command = { path = "../command" }
|
||||||
bscreensaver-util = { path = "../util" }
|
bscreensaver-util = { path = "../util" }
|
||||||
|
libc = "0.2"
|
||||||
log = "0.4"
|
log = "0.4"
|
||||||
nix = "0.23"
|
nix = "0.23"
|
||||||
# git source needed until extension event error resolution fix is released
|
# git source needed until extension event error resolution fix is released
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
#![feature(linux_pidfd)]
|
#![cfg_attr(feature = "use-nightly", feature(linux_pidfd))]
|
||||||
#![feature(option_result_contains)]
|
#![cfg_attr(feature = "use-nightly", feature(option_result_contains))]
|
||||||
|
|
||||||
|
#[cfg(not(feature = "use-nightly"))]
|
||||||
|
mod pidfd;
|
||||||
|
|
||||||
use clap::{Arg, Command as ClapCommand};
|
use clap::{Arg, Command as ClapCommand};
|
||||||
use log::{debug, error, info, trace, warn};
|
use log::{debug, error, info, trace, warn};
|
||||||
@ -17,7 +20,6 @@ use std::{
|
|||||||
fs::read_link,
|
fs::read_link,
|
||||||
io::{self, Read},
|
io::{self, Read},
|
||||||
os::{
|
os::{
|
||||||
linux::process::{ChildExt, CommandExt, PidFd},
|
|
||||||
unix::io::AsRawFd,
|
unix::io::AsRawFd,
|
||||||
unix::process::ExitStatusExt,
|
unix::process::ExitStatusExt,
|
||||||
},
|
},
|
||||||
@ -30,6 +32,11 @@ use xcb_xembed::embedder::Embedder;
|
|||||||
use bscreensaver_command::{BCommand, create_command_window};
|
use bscreensaver_command::{BCommand, create_command_window};
|
||||||
use bscreensaver_util::{*, settings::Configuration};
|
use bscreensaver_util::{*, settings::Configuration};
|
||||||
|
|
||||||
|
#[cfg(feature = "use-nightly")]
|
||||||
|
use std::os::linux::process::{ChildExt, CommandExt, PidFd};
|
||||||
|
#[cfg(not(feature = "use-nightly"))]
|
||||||
|
use pidfd::{CreatePidFd, PidFd};
|
||||||
|
|
||||||
const BLANKED_ARG: &str = "blanked";
|
const BLANKED_ARG: &str = "blanked";
|
||||||
const LOCKED_ARG: &str = "locked";
|
const LOCKED_ARG: &str = "locked";
|
||||||
|
|
||||||
@ -202,9 +209,9 @@ fn main() -> anyhow::Result<()> {
|
|||||||
let result = match pfd.as_raw_fd() {
|
let result = match pfd.as_raw_fd() {
|
||||||
fd if fd == signal_fd.as_raw_fd() => handle_signals(&mut state, &mut signal_fd),
|
fd if fd == signal_fd.as_raw_fd() => handle_signals(&mut state, &mut signal_fd),
|
||||||
fd if fd == conn.as_raw_fd() => handle_xcb_events(&conn, &mut state, &command_atoms),
|
fd if fd == conn.as_raw_fd() => handle_xcb_events(&conn, &mut state, &command_atoms),
|
||||||
fd if dbus_service_fd.contains(&fd) => handle_subservice_quit(state.dbus_service.take(), "DBus", || start_dbus_service(&mut state)),
|
fd if opt_contains(&dbus_service_fd, &fd) => handle_subservice_quit(state.dbus_service.take(), "DBus", || start_dbus_service(&mut state)),
|
||||||
fd if systemd_service_fd.contains(&fd) => handle_subservice_quit(state.systemd_service.take(), "systemd", || start_systemd_service(&mut state)),
|
fd if opt_contains(&systemd_service_fd, &fd) => handle_subservice_quit(state.systemd_service.take(), "systemd", || start_systemd_service(&mut state)),
|
||||||
fd if dialog_fd.contains(&fd) => handle_unlock_dialog_quit(&conn, &mut state),
|
fd if opt_contains(&dialog_fd, &fd) => handle_unlock_dialog_quit(&conn, &mut state),
|
||||||
_ => Ok(()),
|
_ => Ok(()),
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -425,10 +432,16 @@ fn create_blanker_windows(conn: &xcb::Connection) -> xcb::Result<Vec<Monitor>> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn start_subservice(binary_name: &str) -> anyhow::Result<(Child, PidFd)> {
|
fn start_subservice(binary_name: &str) -> anyhow::Result<(Child, PidFd)> {
|
||||||
let mut child = Command::new(format!("{}/{}", env!("HELPER_DIR"), binary_name))
|
let mut command = Command::new(format!("{}/{}", env!("HELPER_DIR"), binary_name));
|
||||||
.create_pidfd(true)
|
#[cfg(feature = "use-nightly")]
|
||||||
.spawn()?;
|
command.create_pidfd(true);
|
||||||
|
let mut child = command.spawn()?;
|
||||||
|
|
||||||
|
#[cfg(feature = "use-nightly")]
|
||||||
let pidfd = child.take_pidfd()?;
|
let pidfd = child.take_pidfd()?;
|
||||||
|
#[cfg(not(feature = "use-nightly"))]
|
||||||
|
let pidfd = child.create_pidfd()?;
|
||||||
|
|
||||||
Ok((child, pidfd))
|
Ok((child, pidfd))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -670,13 +683,18 @@ fn start_unlock_dialog<'a>(conn: &'a xcb::Connection, state: &State<'a>, trigger
|
|||||||
state.monitors.iter().nth(0).unwrap()
|
state.monitors.iter().nth(0).unwrap()
|
||||||
});
|
});
|
||||||
|
|
||||||
let mut child = Command::new(format!("{}/{}", env!("HELPER_DIR"), state.config.dialog_backend.binary_name()))
|
let mut command = Command::new(format!("{}/{}", env!("HELPER_DIR"), state.config.dialog_backend.binary_name()));
|
||||||
.create_pidfd(true)
|
#[cfg(feature = "use-nightly")]
|
||||||
|
command.create_pidfd(true);
|
||||||
|
let mut child = command
|
||||||
.stdout(Stdio::piped())
|
.stdout(Stdio::piped())
|
||||||
.spawn()?;
|
.spawn()?;
|
||||||
|
|
||||||
let mut child_out = child.stdout.take().unwrap();
|
let mut child_out = child.stdout.take().unwrap();
|
||||||
|
#[cfg(feature = "use-nightly")]
|
||||||
let child_pidfd = child.take_pidfd()?;
|
let child_pidfd = child.take_pidfd()?;
|
||||||
|
#[cfg(not(feature = "use-nightly"))]
|
||||||
|
let child_pidfd = child.create_pidfd()?;
|
||||||
|
|
||||||
let mut xid_buf: [u8; 4] = [0; 4];
|
let mut xid_buf: [u8; 4] = [0; 4];
|
||||||
child_out.read_exact(&mut xid_buf)?;
|
child_out.read_exact(&mut xid_buf)?;
|
||||||
@ -913,3 +931,12 @@ fn kill_child_processes(state: &mut State) -> anyhow::Result<()> {
|
|||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn opt_contains<T: PartialEq>(o: &Option<T>, v: &T) -> bool {
|
||||||
|
#[cfg(feature = "use-nightly")]
|
||||||
|
let res = o.contains(v);
|
||||||
|
#[cfg(not(feature = "use-nightly"))]
|
||||||
|
let res = o.as_ref().filter(|ov| ov == &v).is_some();
|
||||||
|
|
||||||
|
res
|
||||||
|
}
|
||||||
|
45
locker/src/pidfd.rs
Normal file
45
locker/src/pidfd.rs
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
use std::{os::unix::io::{AsRawFd, RawFd}, process::Child};
|
||||||
|
|
||||||
|
fn pidfd_open(pid: RawFd) -> nix::Result<PidFd> {
|
||||||
|
// SAFETY: passing arguments as specified for pidfd_open()
|
||||||
|
match unsafe { libc::syscall(libc::SYS_pidfd_open, pid as libc::pid_t, 0 as libc::c_uint) } {
|
||||||
|
fd if fd >= 0 => Ok(PidFd(fd as RawFd)),
|
||||||
|
_ => {
|
||||||
|
// SAFETY: libc must be sane
|
||||||
|
let errno_location = unsafe { libc::__errno_location() };
|
||||||
|
if errno_location.is_null() {
|
||||||
|
Err(nix::errno::Errno::UnknownErrno)
|
||||||
|
} else {
|
||||||
|
// SAFETY: pointer is checked for null; libc must be sane
|
||||||
|
let errno = unsafe { *errno_location };
|
||||||
|
Err(nix::errno::Errno::from_i32(errno))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct PidFd(RawFd);
|
||||||
|
|
||||||
|
pub trait CreatePidFd {
|
||||||
|
// mut isn't necessary here, but it is for the nightly PidFd stuff,
|
||||||
|
// so keep it like this to avoid a warning when compiling using stable.
|
||||||
|
fn create_pidfd(&mut self) -> nix::Result<PidFd>;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl CreatePidFd for Child {
|
||||||
|
fn create_pidfd(&mut self) -> nix::Result<PidFd> {
|
||||||
|
pidfd_open(self.id() as RawFd)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AsRawFd for PidFd {
|
||||||
|
fn as_raw_fd(&self) -> RawFd {
|
||||||
|
self.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Drop for PidFd {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
let _ = nix::unistd::close(self.0);
|
||||||
|
}
|
||||||
|
}
|
@ -1 +0,0 @@
|
|||||||
nightly
|
|
Loading…
Reference in New Issue
Block a user