diff --git a/Cargo.toml b/Cargo.toml index c7316d3..1591432 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -33,7 +33,6 @@ desktop = [ "dep:freedesktop-desktop-entry", "dep:mime", "dep:shlex", - "dep:tokio", "dep:textdistance", "dep:zbus", ] @@ -42,7 +41,7 @@ serde-keycode = ["iced_core/serde"] # Prevents multiple separate process instances. single-instance = ["dep:zbus", "ron"] # smol async runtime -smol = ["iced/smol", "zbus?/async-io"] +smol = ["dep:smol", "iced/smol", "zbus?/async-io"] tokio = [ "dep:tokio", "ashpd?/tokio", @@ -92,13 +91,14 @@ rfd = { version = "0.14.0", optional = true } rustix = { version = "0.38.34", features = ["pipe", "process"], optional = true } serde = { version = "1.0.180", features = ["derive"] } slotmap = "1.0.6" +smol = { version = "2.0.0", optional = true } textdistance = { version = "1.0.2", optional = true } thiserror = "1.0.44" tokio = { version = "1.24.2", optional = true } tracing = "0.1" unicode-segmentation = "1.6" url = "2.4.0" -zbus = { version = "4.2.1", default-features = false, features = ["tokio"], optional = true } +zbus = { version = "4.2.1", default-features = false, optional = true } [target.'cfg(unix)'.dependencies] freedesktop-icons = "0.2.5" diff --git a/src/process.rs b/src/process.rs index 155cb1d..e6a5c09 100644 --- a/src/process.rs +++ b/src/process.rs @@ -1,8 +1,26 @@ +#[cfg(all(feature = "smol", not(feature = "tokio")))] +use smol::io::AsyncReadExt; use std::fs::File; use std::io; +use std::os::fd::OwnedFd; use std::process::{exit, Command, Stdio}; +#[cfg(feature = "tokio")] use tokio::io::AsyncReadExt; +#[cfg(feature = "tokio")] +async fn read_from_pipe(read: OwnedFd) -> Option { + let mut read = tokio::net::unix::pipe::Receiver::from_owned_fd(read).unwrap(); + read.read_u32().await.ok() +} + +#[cfg(all(feature = "smol", not(feature = "tokio")))] +async fn read_from_pipe(read: OwnedFd) -> Option { + let mut read = smol::Async::new(std::fs::File::from(read)).unwrap(); + let mut bytes = [0; 4]; + read.read_exact(&mut bytes).await.ok()?; + Some(u32::from_be_bytes(bytes)) +} + /// Performs a double fork with setsid to spawn and detach a command. pub async fn spawn(mut command: Command) -> Option { command @@ -17,10 +35,9 @@ pub async fn spawn(mut command: Command) -> Option { match unsafe { libc::fork() } { // Parent process 1.. => { + // Drop copy of write end, then read PID from pipe drop(write); - // Read PID from pipe - let mut read = tokio::net::unix::pipe::Receiver::from_owned_fd(read).unwrap(); - read.read_u32().await.ok() + read_from_pipe(read).await } // Child process