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 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 #[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 #[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}