qrexec_binds/
lib.rs

1pub mod errors;
2
3use std::{
4    io::{Write, Read, self},
5    process::{
6        Command,
7        Child,
8        ChildStdout,
9        ChildStdin,
10        ChildStderr,
11    },
12};
13use anyhow::anyhow;
14use crate::errors::*;
15
16#[derive(Debug)]
17pub struct Qrexec { 
18    pub child: Child,
19    pub stdout: ChildStdout,
20    pub stdin: ChildStdin,
21    pub stderr: ChildStderr,
22}
23
24impl Qrexec {
25    /// Calls qrexec-client-vm with the arguments provided through the args parameter.
26    ///
27    /// # Examples 
28    ///
29    /// ```
30    /// let qrx = Qrexec::new(&[
31    ///     "--buffer-size=10",
32    ///     "target_vmname",
33    ///     "rpc_service_on_target_vmname",
34    /// ]);
35    ///
36    /// Qrexec::write(&mut qrx.stdin, &[0, 1, 2])?;
37    /// ```
38    pub fn new(args: &[&str]) -> QRXRes<Self> {
39        const STDOUT_ERR: &str = 
40            "Error: child proc failed to produce stdout";
41        const STDIN_ERR: &str = 
42            "Error: child proc failed to produce stdin";
43        const STDERR_ERR: &str =
44            "Error: child proc failed to produce stderr";
45
46        let mut child = Command::new("qrexec-client-vm")
47            .args(args)
48            .spawn()?;
49        return Ok(Self {
50            stdout: child.stdout.take().ok_or(
51                anyhow!(STDOUT_ERR))?,
52            stdin: child.stdin.take().ok_or(
53                anyhow!(STDIN_ERR))?,
54            stderr: child.stderr.take().ok_or(
55                anyhow!(STDERR_ERR))?,
56            child,
57        })
58    }
59
60    // wrote these so I can put error handling in here
61    // once i test the errors that pop out. 
62
63    /// returns the number of bytes read into the buffer 
64    /// currently this is a direct inlined call the  
65    /// standard libraries read function. 
66    #[inline(always)]
67    pub fn read(
68        read: &mut impl Read,
69        buf: &mut [u8],
70    ) -> Result<usize, io::Error> {
71        match read.read(buf) {
72            Ok(nb) => Ok(nb),
73            Err(e) => Err(e),
74        }
75    } 
76
77    /// returns the number of bytes written into the buffer
78    /// currently this is a direct inlined call the  
79    /// standard libraries read function. 
80    #[inline(always)]
81    pub fn write(
82        written: &mut impl Write,
83        buf: &[u8],
84    ) -> Result<usize, io::Error> {
85        match written.write(buf) {
86            Ok(nb) => Ok(nb),
87            Err(e) => Err(e),
88        }
89    }
90}
91
92impl Drop for Qrexec {
93    fn drop(&mut self) {
94        let _ = self.child.kill();   
95    }
96}