i3status_rs/
subprocess.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
use std::io;
use std::os::unix::process::CommandExt;
use std::process::{Command, Stdio};

/// Spawn a new detached process
pub fn spawn_process(cmd: &str, args: &[&str]) -> io::Result<()> {
    let mut proc = Command::new(cmd);
    proc.args(args);
    proc.stdin(Stdio::null());
    proc.stdout(Stdio::null());
    // Safety: libc::daemon() is async-signal-safe
    unsafe {
        proc.pre_exec(|| match libc::daemon(0, 0) {
            -1 => Err(io::Error::new(
                io::ErrorKind::Other,
                "Failed to detach new process",
            )),
            _ => Ok(()),
        });
    }
    proc.spawn()?.wait()?;
    Ok(())
}

/// Spawn a new detached shell
pub fn spawn_shell(cmd: &str) -> io::Result<()> {
    spawn_process("sh", &["-c", cmd])
}

pub async fn spawn_shell_sync(cmd: &str) -> io::Result<()> {
    tokio::process::Command::new("sh")
        .args(["-c", cmd])
        .stdin(Stdio::null())
        .stdout(Stdio::null())
        .spawn()?
        .wait()
        .await?;
    Ok(())
}