Accept -listenfd and pass on to Xwayland
This commit is contained in:
parent
ac391db415
commit
9e48795087
3 changed files with 64 additions and 11 deletions
14
src/lib.rs
14
src/lib.rs
|
|
@ -8,7 +8,7 @@ use log::{error, info};
|
||||||
use rustix::event::{poll, PollFd, PollFlags};
|
use rustix::event::{poll, PollFd, PollFlags};
|
||||||
use smithay_client_toolkit::data_device_manager::WritePipe;
|
use smithay_client_toolkit::data_device_manager::WritePipe;
|
||||||
use std::io::{BufRead, BufReader, Read, Write};
|
use std::io::{BufRead, BufReader, Read, Write};
|
||||||
use std::os::fd::{AsFd, AsRawFd, BorrowedFd};
|
use std::os::fd::{AsFd, AsRawFd, BorrowedFd, OwnedFd};
|
||||||
use std::os::unix::net::UnixStream;
|
use std::os::unix::net::UnixStream;
|
||||||
use std::process::{Command, ExitStatus, Stdio};
|
use std::process::{Command, ExitStatus, Stdio};
|
||||||
use wayland_server::{Display, ListeningSocket};
|
use wayland_server::{Display, ListeningSocket};
|
||||||
|
|
@ -35,6 +35,7 @@ type RealServerState = ServerState<RealConnection>;
|
||||||
|
|
||||||
pub trait RunData {
|
pub trait RunData {
|
||||||
fn display(&self) -> Option<&str>;
|
fn display(&self) -> Option<&str>;
|
||||||
|
fn listenfds(&mut self) -> Vec<OwnedFd>;
|
||||||
fn server(&self) -> Option<UnixStream> {
|
fn server(&self) -> Option<UnixStream> {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
@ -46,7 +47,7 @@ pub trait RunData {
|
||||||
fn xwayland_ready(&self, _display: String, _pid: u32) {}
|
fn xwayland_ready(&self, _display: String, _pid: u32) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn main(data: impl RunData) -> Option<()> {
|
pub fn main(mut data: impl RunData) -> Option<()> {
|
||||||
let mut version = env!("VERGEN_GIT_DESCRIBE");
|
let mut version = env!("VERGEN_GIT_DESCRIBE");
|
||||||
if version == "VERGEN_IDEMPOTENT_OUTPUT" {
|
if version == "VERGEN_IDEMPOTENT_OUTPUT" {
|
||||||
version = env!("CARGO_PKG_VERSION");
|
version = env!("CARGO_PKG_VERSION");
|
||||||
|
|
@ -70,6 +71,12 @@ pub fn main(data: impl RunData) -> Option<()> {
|
||||||
if let Some(display) = data.display() {
|
if let Some(display) = data.display() {
|
||||||
xwayland.arg(display);
|
xwayland.arg(display);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let fds = data.listenfds();
|
||||||
|
for fd in &fds {
|
||||||
|
xwayland.args(["-listenfd", &fd.as_raw_fd().to_string()]);
|
||||||
|
}
|
||||||
|
|
||||||
let mut xwayland = xwayland
|
let mut xwayland = xwayland
|
||||||
.args([
|
.args([
|
||||||
"-rootless",
|
"-rootless",
|
||||||
|
|
@ -84,6 +91,9 @@ pub fn main(data: impl RunData) -> Option<()> {
|
||||||
.spawn()
|
.spawn()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
|
// Now that Xwayland spawned and got the listenfds, we can close them here.
|
||||||
|
drop(fds);
|
||||||
|
|
||||||
let xwl_pid = xwayland.id();
|
let xwl_pid = xwayland.id();
|
||||||
|
|
||||||
let (mut finish_tx, mut finish_rx) = UnixStream::pair().unwrap();
|
let (mut finish_tx, mut finish_rx) = UnixStream::pair().unwrap();
|
||||||
|
|
|
||||||
55
src/main.rs
55
src/main.rs
|
|
@ -1,24 +1,63 @@
|
||||||
|
use std::os::fd::{FromRawFd, OwnedFd, RawFd};
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
pretty_env_logger::formatted_timed_builder()
|
pretty_env_logger::formatted_timed_builder()
|
||||||
.filter_level(log::LevelFilter::Info)
|
.filter_level(log::LevelFilter::Info)
|
||||||
.parse_default_env()
|
.parse_default_env()
|
||||||
.init();
|
.init();
|
||||||
xwayland_satellite::main(RealData(get_display()));
|
xwayland_satellite::main(parse_args());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[repr(transparent)]
|
struct RealData {
|
||||||
struct RealData(Option<String>);
|
display: Option<String>,
|
||||||
|
listenfds: Vec<OwnedFd>,
|
||||||
|
}
|
||||||
impl xwayland_satellite::RunData for RealData {
|
impl xwayland_satellite::RunData for RealData {
|
||||||
fn display(&self) -> Option<&str> {
|
fn display(&self) -> Option<&str> {
|
||||||
self.0.as_deref()
|
self.display.as_deref()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn listenfds(&mut self) -> Vec<OwnedFd> {
|
||||||
|
std::mem::take(&mut self.listenfds)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_display() -> Option<String> {
|
fn parse_args() -> RealData {
|
||||||
|
let mut data = RealData {
|
||||||
|
display: None,
|
||||||
|
listenfds: Vec::new(),
|
||||||
|
};
|
||||||
|
|
||||||
let mut args: Vec<_> = std::env::args().collect();
|
let mut args: Vec<_> = std::env::args().collect();
|
||||||
if args.len() > 2 {
|
if args.len() < 2 {
|
||||||
panic!("Unexpected arguments: {:?}", &args[2..]);
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
(args.len() == 2).then(|| args.swap_remove(1))
|
// Argument at index 1 is our display name. The rest can be -listenfd.
|
||||||
|
let mut i = 2;
|
||||||
|
while i < args.len() {
|
||||||
|
let arg = &args[i];
|
||||||
|
if arg == "-listenfd" {
|
||||||
|
let next = i + 1;
|
||||||
|
if next == args.len() {
|
||||||
|
// Matches the Xwayland error message.
|
||||||
|
panic!("Required argument to -listenfd not specified");
|
||||||
|
}
|
||||||
|
|
||||||
|
let fd: RawFd = args[next].parse().expect("Error parsing -listenfd number");
|
||||||
|
// SAFETY:
|
||||||
|
// - whoever runs the binary must ensure this fd is open and valid.
|
||||||
|
// - parse_args() must only be called once to avoid double closing.
|
||||||
|
let fd = unsafe { OwnedFd::from_raw_fd(fd) };
|
||||||
|
|
||||||
|
data.listenfds.push(fd);
|
||||||
|
i += 2;
|
||||||
|
} else {
|
||||||
|
panic!("Unrecognized argument: {arg}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
data.display = Some(args.swap_remove(1));
|
||||||
|
|
||||||
|
data
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ use rustix::process::{Pid, Signal, WaitOptions};
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
use std::mem::ManuallyDrop;
|
use std::mem::ManuallyDrop;
|
||||||
use std::os::fd::{AsRawFd, BorrowedFd};
|
use std::os::fd::{AsRawFd, BorrowedFd, OwnedFd};
|
||||||
use std::os::unix::net::UnixStream;
|
use std::os::unix::net::UnixStream;
|
||||||
use std::sync::{
|
use std::sync::{
|
||||||
atomic::{AtomicBool, Ordering},
|
atomic::{AtomicBool, Ordering},
|
||||||
|
|
@ -72,6 +72,10 @@ impl xwls::RunData for TestData {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn listenfds(&mut self) -> Vec<OwnedFd> {
|
||||||
|
Vec::new()
|
||||||
|
}
|
||||||
|
|
||||||
fn server(&self) -> Option<UnixStream> {
|
fn server(&self) -> Option<UnixStream> {
|
||||||
let mut server = self.server.lock().unwrap();
|
let mut server = self.server.lock().unwrap();
|
||||||
assert!(server.is_some());
|
assert!(server.is_some());
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue