From d5e9ed5b8de9fbfbd3bcb01ee8ec07ecd66dd0a2 Mon Sep 17 00:00:00 2001 From: Ian Jackson Date: Tue, 22 Dec 2020 23:02:31 +0000 Subject: [PATCH] wip Xvfb Signed-off-by: Ian Jackson --- wdriver.rs | 57 +++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 50 insertions(+), 7 deletions(-) diff --git a/wdriver.rs b/wdriver.rs index 0bf4b476..93947755 100644 --- a/wdriver.rs +++ b/wdriver.rs @@ -9,15 +9,14 @@ pub use void::Void; pub use std::env; pub use std::fs; -pub use std::io::{ErrorKind, Write}; +pub use std::io::{BufRead, BufReader, ErrorKind, Write}; pub use std::os::unix::process::CommandExt; pub use std::os::unix::fs::DirBuilderExt; pub use std::os::linux::fs::MetadataExt; // todo why linux for st_mode?? -pub use std::process::Command; +pub use std::process::{Command, Stdio}; pub type AE = anyhow::Error; - #[derive(Debug,Clone)] #[derive(StructOpt)] struct Opts { @@ -31,17 +30,22 @@ struct Opts { #[derive(Debug,Clone)] pub struct Setup { tmp: String, + display: String, } +const XSOCKETS : &str = "/tmp/.X11-unix"; + #[throws(AE)] fn reinvoke_via_bwrap(_opts: &Opts, current_exe: &str) -> Void { println!("running bwrap"); let mut bcmd = Command::new("bwrap"); - bcmd.args("--unshare-net \ - --dev-bind / / \ - --tmpfs /tmp \ - --die-with-parent".split(" ")) + bcmd + .args("--unshare-net \ + --dev-bind / / \ + --tmpfs /tmp \ + --die-with-parent".split(" ")) + .args(&["--dir", XSOCKETS]) .arg(current_exe) .arg("--no-bwrap") .args(env::args_os().skip(1)); @@ -103,6 +107,40 @@ fn prepare_tmpdir(opts: &Opts, current_exe: &str) -> String { our_tmpdir } +#[throws(AE)] +fn prepare_xserver1() -> impl FnOnce() -> Result { + const DISPLAY : &str = "12"; + + let mut xcmd = Command::new("Xvfb"); + xcmd + .args("-displayfd 1 :12".split(' ')) + .stdout(Stdio::piped()); + let mut child = xcmd.spawn() + .context("spawn Xvfb")?; + let mut report = BufReader::new(child.stdout.take().unwrap()).lines(); + + move ||{ + let l = report.next(); + + let s = child.try_wait().context("check on Xvfb")?; + if let Some(e) = s { + throw!(anyhow!("Xvfb failed to start: wait status = {}", &e)); + } + + let l = match l { + Some(Ok(l)) if l == DISPLAY => { l }, + Some(Ok(l)) => throw!(anyhow!( + "Xfvb said {:?}, expected {:?}", + l, DISPLAY + )), + None => throw!(anyhow!("EOF from Xvfb (but it's still running?")), + Some(Err(e)) => throw!(AE::from(e).context("failed to read from Xfvb")), + }; + + Ok(l) + } +} + #[throws(AE)] pub fn setup() -> Setup { let current_exe : String = env::current_exe() @@ -119,7 +157,12 @@ pub fn setup() -> Setup { let tmp = prepare_tmpdir(&opts, ¤t_exe)?; + let xserver1 = prepare_xserver1().context("setup X server")?; + + let display = xserver1().context("wait for X server")?; + Setup { tmp, + display, } } -- 2.30.2