Use tokio to asynchronously read from pipe
Avoids either `spawn_blocking`, or potentially blocking call in an async function (though it shouldn't block for long).
This commit is contained in:
parent
621de17cad
commit
82fb781746
2 changed files with 8 additions and 12 deletions
|
|
@ -335,7 +335,7 @@ where
|
||||||
// https://systemd.io/DESKTOP_ENVIRONMENTS
|
// https://systemd.io/DESKTOP_ENVIRONMENTS
|
||||||
//
|
//
|
||||||
// Similar to what Gnome sets, for now.
|
// Similar to what Gnome sets, for now.
|
||||||
if let Ok(Some(pid)) = tokio::task::spawn_blocking(|| crate::process::spawn(cmd)).await {
|
if let Some(pid) = crate::process::spawn(cmd).await {
|
||||||
if let Ok(session) = zbus::Connection::session().await {
|
if let Ok(session) = zbus::Connection::session().await {
|
||||||
if let Ok(systemd_manager) = SystemdMangerProxy::new(&session).await {
|
if let Ok(systemd_manager) = SystemdMangerProxy::new(&session).await {
|
||||||
let _ = systemd_manager
|
let _ = systemd_manager
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,10 @@
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io;
|
use std::io;
|
||||||
use std::process::{exit, Command, Stdio};
|
use std::process::{exit, Command, Stdio};
|
||||||
|
use tokio::io::AsyncReadExt;
|
||||||
|
|
||||||
/// Performs a double fork with setsid to spawn and detach a command.
|
/// Performs a double fork with setsid to spawn and detach a command.
|
||||||
pub fn spawn(mut command: Command) -> Option<u32> {
|
pub async fn spawn(mut command: Command) -> Option<u32> {
|
||||||
command
|
command
|
||||||
.stdin(Stdio::null())
|
.stdin(Stdio::null())
|
||||||
.stdout(Stdio::null())
|
.stdout(Stdio::null())
|
||||||
|
|
@ -15,16 +16,11 @@ pub fn spawn(mut command: Command) -> Option<u32> {
|
||||||
|
|
||||||
match unsafe { libc::fork() } {
|
match unsafe { libc::fork() } {
|
||||||
// Parent process
|
// Parent process
|
||||||
child @ 1.. => {
|
1.. => {
|
||||||
let child = rustix::process::Pid::from_raw(child).unwrap();
|
drop(write);
|
||||||
let _res = rustix::process::waitpid(Some(child), rustix::process::WaitOptions::empty());
|
|
||||||
// Read PID from pipe
|
// Read PID from pipe
|
||||||
let mut bytes = [0; 4];
|
let mut read = tokio::net::unix::pipe::Receiver::from_owned_fd(read).unwrap();
|
||||||
if rustix::io::read(read, &mut bytes) == Ok(4) {
|
read.read_u32().await.ok()
|
||||||
Some(u32::from_ne_bytes(bytes))
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Child process
|
// Child process
|
||||||
|
|
@ -32,7 +28,7 @@ pub fn spawn(mut command: Command) -> Option<u32> {
|
||||||
let _res = rustix::process::setsid();
|
let _res = rustix::process::setsid();
|
||||||
if let Ok(child) = command.spawn() {
|
if let Ok(child) = command.spawn() {
|
||||||
// Write PID to pipe
|
// Write PID to pipe
|
||||||
let _ = rustix::io::write(write, &child.id().to_ne_bytes());
|
let _ = rustix::io::write(write, &child.id().to_be_bytes());
|
||||||
}
|
}
|
||||||
|
|
||||||
exit(0)
|
exit(0)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue