Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 17 additions & 12 deletions crates/muvm/src/bin/muvm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,7 @@ fn main() -> Result<ExitCode> {
}
}

let mut enable_hidpipe = false;
if let Ok(run_path) = env::var("XDG_RUNTIME_DIR") {
let pulse_path = Path::new(&run_path).join("pulse/native");
if pulse_path.exists() {
Expand All @@ -309,19 +310,22 @@ fn main() -> Result<ExitCode> {
}

let hidpipe_path = Path::new(&run_path).join("hidpipe");
spawn_hidpipe_server(hidpipe_path.clone()).context("Failed to spawn hidpipe thread")?;
let hidpipe_path = CString::new(
hidpipe_path
.to_str()
.expect("hidpipe_path should not contain invalid UTF-8"),
)
.context("Failed to process `hidpipe` path as it contains NUL character")?;
enable_hidpipe =
spawn_hidpipe_server(hidpipe_path.clone()).context("Failed to spawn hidpipe thread")?;
if enable_hidpipe {
let hidpipe_path = CString::new(
hidpipe_path
.to_str()
.expect("hidpipe_path should not contain invalid UTF-8"),
)
.context("Failed to process `hidpipe` path as it contains NUL character")?;

// SAFETY: `hidpipe_path` is a pointer to a `CString` with long enough lifetime.
let err = unsafe { krun_add_vsock_port(ctx_id, HIDPIPE_SOCKET, hidpipe_path.as_ptr()) };
if err < 0 {
let err = Errno::from_raw_os_error(-err);
return Err(err).context("Failed to configure vsock for hidpipe socket");
// SAFETY: `hidpipe_path` is a pointer to a `CString` with long enough lifetime.
let err = unsafe { krun_add_vsock_port(ctx_id, HIDPIPE_SOCKET, hidpipe_path.as_ptr()) };
if err < 0 {
let err = Errno::from_raw_os_error(-err);
return Err(err).context("Failed to configure vsock for hidpipe socket");
}
}

let socket_dir = Path::new(&run_path).join("krun/socket");
Expand Down Expand Up @@ -413,6 +417,7 @@ fn main() -> Result<ExitCode> {
cwd,
init_commands,
user_init_commands: options.user_init_commands,
enable_hidpipe,
};
let mut muvm_config_file = NamedTempFile::new()
.context("Failed to create a temporary file to store the muvm guest config")?;
Expand Down
16 changes: 10 additions & 6 deletions crates/muvm/src/guest/bin/muvm-guest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -147,12 +147,16 @@ fn main() -> Result<ExitCode> {
setup_x11_forwarding(run_path, &host_display)?;
}

let uid = options.uid;
thread::spawn(move || {
if catch_unwind(|| start_hidpipe(uid)).is_err() {
eprintln!("hidpipe thread crashed, input device passthrough will no longer function");
}
});
if options.enable_hidpipe {
let uid = options.uid;
thread::spawn(move || {
if catch_unwind(|| start_hidpipe(uid)).is_err() {
eprintln!(
"hidpipe thread crashed, input device passthrough will no longer function"
);
}
});
}

thread::spawn(|| {
if catch_unwind(start_pwbridge).is_err() {
Expand Down
16 changes: 11 additions & 5 deletions crates/muvm/src/hidpipe_server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -280,12 +280,18 @@ where
}
}

pub fn spawn_hidpipe_server(socket_path: PathBuf) -> anyhow::Result<()> {
pub fn spawn_hidpipe_server(socket_path: PathBuf) -> anyhow::Result<bool> {
let mut evdevs = EvdevContainer::new();
let epoll = Epoll::new(EpollCreateFlags::empty()).context("Failed to create epoll object")?;
for dir_ent in
fs::read_dir("/dev/input/").context("Failed to read \"/dev/input/\" directory")?
{
let dir_entries = match fs::read_dir("/dev/input/") {
Ok(entries) => entries,
Err(err) if err.kind() == ErrorKind::NotFound => {
debug!("Skipping hidpipe initialization: /dev/input is not present");
return Ok(false);
},
Err(err) => return Err(err).context("Failed to read \"/dev/input/\" directory"),
};
for dir_ent in dir_entries {
let dir_ent = dir_ent.context("Failed to read directory entry")?;
if dir_ent
.file_type()
Expand Down Expand Up @@ -321,7 +327,7 @@ pub fn spawn_hidpipe_server(socket_path: PathBuf) -> anyhow::Result<()> {
.unwrap();

thread::spawn(move || run(evdevs, listen_sock, epoll));
Ok(())
Ok(true)
}

fn run(mut evdevs: EvdevContainer, listen_sock: UnixListener, epoll: Epoll) {
Expand Down
6 changes: 6 additions & 0 deletions crates/muvm/src/utils/launch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,12 @@ pub struct GuestConfiguration {
pub cwd: PathBuf,
pub init_commands: Vec<PathBuf>,
pub user_init_commands: Vec<PathBuf>,
#[serde(default = "default_true")]
pub enable_hidpipe: bool,
}

fn default_true() -> bool {
true
}

pub const PULSE_SOCKET: u32 = 3333;
Expand Down