nydus_utils/
exec.rs

1// Copyright 2020 Ant Group. All rights reserved.
2//
3// SPDX-License-Identifier: Apache-2.0
4
5use std::io::{Result, Write};
6use std::process::{Command, Stdio};
7
8pub fn exec(cmd: &str, output: bool, input: &[u8]) -> Result<String> {
9    debug!("exec `{}`", cmd);
10    let has_input = !input.is_empty();
11    let mut basic_cmd = Command::new("sh");
12    let mut cmd_object = basic_cmd.arg("-c").arg(cmd).env("RUST_BACKTRACE", "1");
13
14    if has_input {
15        cmd_object = cmd_object.stdin(Stdio::piped());
16    } else {
17        cmd_object = cmd_object.stdin(Stdio::null());
18    }
19
20    if output {
21        cmd_object = cmd_object.stdout(Stdio::piped()).stderr(Stdio::piped());
22    } else {
23        cmd_object = cmd_object.stdout(Stdio::inherit()).stderr(Stdio::inherit())
24    }
25    let mut child = cmd_object.spawn()?;
26
27    if has_input {
28        let mut input_stream = child.stdin.take().unwrap();
29        input_stream.write_all(input)?;
30        drop(input_stream);
31    }
32
33    if output {
34        let output = child.wait_with_output()?;
35        if !output.status.success() {
36            return Err(eother!("exit with non-zero status"));
37        }
38        let stdout = std::str::from_utf8(&output.stdout).map_err(|e| einval!(e))?;
39        return Ok(stdout.to_string());
40    }
41
42    let status = child.wait()?;
43    if !status.success() {
44        return Err(eother!("exit with non-zero status"));
45    }
46
47    Ok(String::from(""))
48}
49
50#[cfg(test)]
51mod tests {
52    use super::*;
53
54    #[test]
55    fn test_exec() {
56        let val = exec("echo hello", true, b"").unwrap();
57        assert_eq!(val, "hello\n");
58
59        let val = exec("echo hello", false, b"").unwrap();
60        assert_eq!(val, "");
61
62        let val = exec("cat -", true, b"test").unwrap();
63        assert_eq!(val, "test");
64
65        let val = exec("cat -", false, b"test").unwrap();
66        assert_eq!(val, "");
67    }
68}