backend.session: use pkg-config to find logind lib

Introduce the `backend_session_elogind` cargo feature which pulls
`backend_session_logind` and makes the logind session backend seek
`libelogind.so` instead of `libsystemd.so`.

Fixes #127
This commit is contained in:
Victor Berger 2020-05-20 00:13:06 +02:00 committed by Victor Berger
parent b05c2ccbba
commit c3859d999b
7 changed files with 113 additions and 22 deletions

View File

@ -65,7 +65,7 @@ jobs:
uses: actions-rs/cargo@v1 uses: actions-rs/cargo@v1
with: with:
command: test command: test
args: --all-features args: --features "test_all_features"
anvil-ci: anvil-ci:
strategy: strategy:
@ -111,7 +111,7 @@ jobs:
- name: Test all - name: Test all
if: matrix.features == 'all' if: matrix.features == 'all'
working-directory: ./anvil working-directory: ./anvil
run: cargo test --all-features run: cargo test --features "test_all_features"
lint: lint:
@ -135,8 +135,8 @@ jobs:
run: cargo fmt --all -- --check run: cargo fmt --all -- --check
- name: Clippy Smithay - name: Clippy Smithay
run: cargo clippy --all-features -- -D warnings run: cargo clippy --features "test_all_features" -- -D warnings
- name: Clippy Anvil - name: Clippy Anvil
working-directory: ./anvil working-directory: ./anvil
run: cargo clippy --all-features -- -D warnings run: cargo clippy --features "test_all_features" -- -D warnings

View File

@ -33,7 +33,7 @@ jobs:
uses: actions-rs/cargo@v1 uses: actions-rs/cargo@v1
with: with:
command: doc command: doc
args: --no-deps --all-features args: --no-deps --features "test_all_features"
- name: Setup index - name: Setup index
run: cp ./doc_index.html ./target/doc/index.html run: cp ./doc_index.html ./target/doc/index.html

View File

@ -20,11 +20,11 @@ glium = { version = "0.27.0", optional = true, default-features = false }
image = { version = "0.23.0", optional = true } image = { version = "0.23.0", optional = true }
input = { version = "0.5", default-features = false, optional = true } input = { version = "0.5", default-features = false, optional = true }
lazy_static = "1" lazy_static = "1"
libc = "0.2.70"
libloading = "0.6.0" libloading = "0.6.0"
nix = "0.17" nix = "0.17"
slog = "2" slog = "2"
slog-stdlog = "4" slog-stdlog = "4"
systemd = { version = "0.4.0", optional = true }
tempfile = "3.0" tempfile = "3.0"
thiserror = "1" thiserror = "1"
udev = { version = "0.4", optional = true } udev = { version = "0.4", optional = true }
@ -43,6 +43,7 @@ slog-term = "2.3"
[build-dependencies] [build-dependencies]
gl_generator = { version = "0.14", optional = true } gl_generator = { version = "0.14", optional = true }
pkg-config = { version = "0.3.17", optional = true }
[features] [features]
default = ["backend_winit", "backend_drm_legacy", "backend_drm_atomic", "backend_drm_gbm", "backend_drm_eglstream", "backend_drm_egl", "backend_libinput", "backend_udev", "backend_session_logind", "renderer_glium", "xwayland", "wayland_frontend"] default = ["backend_winit", "backend_drm_legacy", "backend_drm_atomic", "backend_drm_gbm", "backend_drm_eglstream", "backend_drm_egl", "backend_libinput", "backend_udev", "backend_session_logind", "renderer_glium", "xwayland", "wayland_frontend"]
@ -57,12 +58,14 @@ backend_egl = ["gl_generator"]
backend_libinput = ["input"] backend_libinput = ["input"]
backend_session = [] backend_session = []
backend_udev = ["udev"] backend_udev = ["udev"]
backend_session_logind = ["dbus", "systemd", "backend_session"] backend_session_logind = ["dbus", "backend_session", "pkg-config"]
backend_session_elogind = ["backend_session_logind"]
renderer_gl = ["gl_generator"] renderer_gl = ["gl_generator"]
renderer_glium = ["renderer_gl", "glium"] renderer_glium = ["renderer_gl", "glium"]
use_system_lib = ["wayland_frontend", "wayland-sys", "wayland-server/use_system_lib"] use_system_lib = ["wayland_frontend", "wayland-sys", "wayland-server/use_system_lib"]
wayland_frontend = ["wayland-server", "wayland-commons", "wayland-protocols"] wayland_frontend = ["wayland-server", "wayland-commons", "wayland-protocols"]
xwayland = ["wayland_frontend"] xwayland = ["wayland_frontend"]
test_all_features = ["default"]
[[example]] [[example]]
name = "raw_legacy_drm" name = "raw_legacy_drm"

View File

@ -31,3 +31,5 @@ egl = [ "smithay/use_system_lib" ]
winit = [ "smithay/backend_winit" ] winit = [ "smithay/backend_winit" ]
udev = [ "smithay/backend_libinput", "smithay/backend_udev", "smithay/backend_drm_atomic", "smithay/backend_drm_legacy", "smithay/backend_drm_gbm", "smithay/backend_drm_eglstream", "smithay/backend_drm_egl", "smithay/backend_session", "input" ] udev = [ "smithay/backend_libinput", "smithay/backend_udev", "smithay/backend_drm_atomic", "smithay/backend_drm_legacy", "smithay/backend_drm_gbm", "smithay/backend_drm_eglstream", "smithay/backend_drm_egl", "smithay/backend_session", "input" ]
logind = [ "smithay/backend_session_logind" ] logind = [ "smithay/backend_session_logind" ]
elogind = ["logind", "smithay/backend_session_elogind" ]
test_all_features = ["default"]

View File

@ -1,12 +1,8 @@
#[cfg(any(feature = "backend_egl", feature = "renderer_gl"))] #[cfg(any(feature = "backend_egl", feature = "renderer_gl"))]
extern crate gl_generator; fn gl_generate() {
use gl_generator::{Api, Fallbacks, Profile, Registry};
use std::{env, fs::File, path::PathBuf};
#[cfg(any(feature = "backend_egl", feature = "renderer_gl"))]
use gl_generator::{Api, Fallbacks, Profile, Registry};
use std::{env, fs::File, path::PathBuf};
#[cfg(any(feature = "backend_egl", feature = "renderer_gl"))]
fn main() {
let dest = PathBuf::from(&env::var("OUT_DIR").unwrap()); let dest = PathBuf::from(&env::var("OUT_DIR").unwrap());
println!("cargo:rerun-if-changed=build.rs"); println!("cargo:rerun-if-changed=build.rs");
@ -63,5 +59,42 @@ fn main() {
} }
} }
#[cfg(not(any(feature = "backend_egl", feature = "renderer_gl")))] #[cfg(feature = "backend_session_logind")]
fn main() {} fn find_logind() {
// We should allow only dynamic linkage due to libsystemd and libelogind LICENSE.
#[cfg(feature = "backend_session_elogind")]
{
if pkg_config::Config::new()
.statik(false)
.probe("libelogind")
.is_err()
{
println!("cargo:warning=Could not find `libelogind.so`.");
println!("cargo:warning=If your system is systemd-based, you should only enable the `backend_session_logind` feature, not `backend_session_elogind`.");
std::process::exit(1);
}
}
#[cfg(not(feature = "backend_session_elogind"))]
{
if pkg_config::Config::new()
.statik(false)
.probe("libsystemd")
.is_err()
{
println!("cargo:warning=Could not find `libsystemd.so`.");
println!("cargo:warning=If your system uses elogind, please enable the `backend_session_elogind` feature.");
println!("cargo:warning=Otherwise, you may need to disable the `backend_session_logind` feature as your system does not support it.");
std::process::exit(1);
}
}
}
fn main() {
#[cfg(any(feature = "backend_egl", feature = "renderer_gl"))]
gl_generate();
#[cfg(feature = "backend_session_logind")]
find_logind();
}

View File

@ -52,7 +52,6 @@ use std::{
rc::{Rc, Weak}, rc::{Rc, Weak},
sync::atomic::{AtomicBool, Ordering}, sync::atomic::{AtomicBool, Ordering},
}; };
use systemd::login;
use calloop::{EventSource, Poll, Readiness, Token}; use calloop::{EventSource, Poll, Readiness, Token};
@ -91,9 +90,7 @@ impl LogindSession {
.new(o!("smithay_module" => "backend_session", "session_type" => "logind")); .new(o!("smithay_module" => "backend_session", "session_type" => "logind"));
// Acquire session_id, seat and vt (if any) via libsystemd // Acquire session_id, seat and vt (if any) via libsystemd
let session_id = login::get_session(None).map_err(Error::FailedToGetSession)?; let (session_id, seat, vt) = ffi::get_login_state()?;
let seat = login::get_seat(session_id.clone()).map_err(Error::FailedToGetSeat)?;
let vt = login::get_vt(session_id.clone()).ok();
// Create dbus connection // Create dbus connection
let conn = DBusConnection::new_system().map_err(Error::FailedDbusConnection)?; let conn = DBusConnection::new_system().map_err(Error::FailedDbusConnection)?;
@ -558,3 +555,61 @@ impl AsErrno for Error {
None None
} }
} }
/*
* FFI routines to retrieve the session state from logind or elogind
*/
mod ffi {
use libc::pid_t;
use std::{
ffi::CString,
os::raw::{c_char, c_int, c_uint},
};
pub fn get_login_state() -> Result<(String, String, Option<u32>), super::Error> {
let session_name = unsafe {
let mut session_name: *mut c_char = std::ptr::null_mut();
let ret = sd_pid_get_session(0, &mut session_name);
if ret < 0 {
return Err(super::Error::FailedToGetSession(
std::io::Error::from_raw_os_error(-ret),
));
}
CString::from_raw(session_name)
};
let seat_name = unsafe {
let mut seat_name: *mut c_char = std::ptr::null_mut();
let ret = sd_session_get_seat(session_name.as_ptr(), &mut seat_name);
if ret < 0 {
return Err(super::Error::FailedToGetSeat(std::io::Error::from_raw_os_error(
-ret,
)));
}
CString::from_raw(seat_name)
};
let vt_num = unsafe {
let mut vt_num = 0;
let ret = sd_session_get_vt(session_name.as_ptr(), &mut vt_num);
if ret < 0 {
None
} else {
Some(vt_num)
}
};
Ok((
session_name.into_string().unwrap(),
seat_name.into_string().unwrap(),
vt_num,
))
}
extern "C" {
fn sd_pid_get_session(pid: pid_t, out_session: *mut *mut c_char) -> c_int;
fn sd_session_get_seat(session: *const c_char, out_seat: *mut *mut c_char) -> c_int;
fn sd_session_get_vt(session: *const c_char, out_vt: *mut c_uint) -> c_int;
}
}

View File

@ -13,8 +13,6 @@ pub use image;
pub use input; pub use input;
#[cfg(any(feature = "backend_udev", feature = "backend_drm"))] #[cfg(any(feature = "backend_udev", feature = "backend_drm"))]
pub use nix; pub use nix;
#[cfg(feature = "backend_session_logind")]
pub use systemd;
#[cfg(feature = "backend_udev")] #[cfg(feature = "backend_udev")]
pub use udev; pub use udev;
#[cfg(feature = "wayland_frontend")] #[cfg(feature = "wayland_frontend")]