Support stable rust

This removes use of Option.contains(), and provides a fallback pidfd
implementation for stable.
This commit is contained in:
Brian Tarricone 2022-05-05 12:16:50 -07:00
parent 04650b3c53
commit 23fef4d9e3
7 changed files with 103 additions and 22 deletions

1
Cargo.lock generated
View File

@ -260,6 +260,7 @@ dependencies = [
"bscreensaver-command",
"bscreensaver-util",
"clap",
"libc",
"log",
"nix",
"xcb",

View File

@ -17,15 +17,22 @@ HELPERS = \
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
all: release
release:
HELPER_DIR=$(HELPER_DIR) cargo build --release
HELPER_DIR=$(HELPER_DIR) cargo $(RUST_RELEASE_CHANNEL_ARG) build $(FEATURES_ARGS) --release
dev:
HELPER_DIR=target/debug cargo build
HELPER_DIR=target/debug cargo $(RUST_RELEASE_CHANNEL_ARG) build $(FEATURES_ARGS)
install: release
$(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)
clean:
cargo clean
cargo $(RUST_RELEASE_CHANNEL_ARG) clean
uninstall:
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_DIALOG_GTK3_LOG=$(DEV_LOG_LEVEL) \
HELPER_DIR=target/debug \
cargo run --bin bscreensaver
cargo $(RUST_RELEASE_CHANNEL_ARG) run $(FEATURES_ARGS) --bin bscreensaver
run-dialog:
RUST_BACKTRACE=1 \
BSCREENSAVER_DIALOG_GTK3_LOG=$(DEV_LOG_LEVEL) \
BSCREENSAVER_DIALOG_STANDALONE=1 \
cargo run --bin bscreensaver-dialog-gtk3
cargo $(RUST_RELEASE_CHANNEL_ARG) run $(FEATURES_ARGS) --bin bscreensaver-dialog-gtk3

View File

@ -1,6 +1,3 @@
#![feature(option_result_contains)]
#![feature(is_some_with)]
use async_std::{fs::File, prelude::*, sync::{Arc, Mutex}, task};
use bscreensaver_util::init_logging;
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()?;
match args.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);
exit(0);
}
@ -168,7 +165,7 @@ async fn dbus_task(state: Arc<Mutex<State>>) -> anyhow::Result<()> {
BusName::Unique(name) => {
if args.new_owner().is_none() {
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);
false
} else {

View File

@ -12,11 +12,16 @@ readme = "README.md"
keywords = ["gui", "screensaver", "screen-locker"]
categories = ["gui"]
[features]
default = ["use-nightly"]
use-nightly = []
[dependencies]
anyhow = "1"
clap = "3"
bscreensaver-command = { path = "../command" }
bscreensaver-util = { path = "../util" }
libc = "0.2"
log = "0.4"
nix = "0.23"
# git source needed until extension event error resolution fix is released

View File

@ -1,5 +1,8 @@
#![feature(linux_pidfd)]
#![feature(option_result_contains)]
#![cfg_attr(feature = "use-nightly", feature(linux_pidfd))]
#![cfg_attr(feature = "use-nightly", feature(option_result_contains))]
#[cfg(not(feature = "use-nightly"))]
mod pidfd;
use clap::{Arg, Command as ClapCommand};
use log::{debug, error, info, trace, warn};
@ -17,7 +20,6 @@ use std::{
fs::read_link,
io::{self, Read},
os::{
linux::process::{ChildExt, CommandExt, PidFd},
unix::io::AsRawFd,
unix::process::ExitStatusExt,
},
@ -30,6 +32,11 @@ use xcb_xembed::embedder::Embedder;
use bscreensaver_command::{BCommand, create_command_window};
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 LOCKED_ARG: &str = "locked";
@ -202,9 +209,9 @@ fn main() -> anyhow::Result<()> {
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 == 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 systemd_service_fd.contains(&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(&dbus_service_fd, &fd) => handle_subservice_quit(state.dbus_service.take(), "DBus", || start_dbus_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 opt_contains(&dialog_fd, &fd) => handle_unlock_dialog_quit(&conn, &mut state),
_ => 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)> {
let mut child = Command::new(format!("{}/{}", env!("HELPER_DIR"), binary_name))
.create_pidfd(true)
.spawn()?;
let mut command = Command::new(format!("{}/{}", env!("HELPER_DIR"), binary_name));
#[cfg(feature = "use-nightly")]
command.create_pidfd(true);
let mut child = command.spawn()?;
#[cfg(feature = "use-nightly")]
let pidfd = child.take_pidfd()?;
#[cfg(not(feature = "use-nightly"))]
let pidfd = child.create_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()
});
let mut child = Command::new(format!("{}/{}", env!("HELPER_DIR"), state.config.dialog_backend.binary_name()))
.create_pidfd(true)
let mut command = Command::new(format!("{}/{}", env!("HELPER_DIR"), state.config.dialog_backend.binary_name()));
#[cfg(feature = "use-nightly")]
command.create_pidfd(true);
let mut child = command
.stdout(Stdio::piped())
.spawn()?;
let mut child_out = child.stdout.take().unwrap();
#[cfg(feature = "use-nightly")]
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];
child_out.read_exact(&mut xid_buf)?;
@ -913,3 +931,12 @@ fn kill_child_processes(state: &mut State) -> anyhow::Result<()> {
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
View 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);
}
}

View File

@ -1 +0,0 @@
nightly