feat: impl stdin option for process.spawn()

This commit is contained in:
Erica Marigold 2023-09-18 23:27:48 +05:30
parent 2963751f6c
commit 683aba4d91
2 changed files with 39 additions and 3 deletions

View file

@ -7,8 +7,11 @@ use std::{
use dunce::canonicalize;
use mlua::prelude::*;
use os_str_bytes::RawOsString;
use tokio::{io::AsyncWriteExt, task};
use crate::lune::{scheduler::Scheduler, util::TableBuilder};
use crate::lune::{
builtins::process::tee_writer::AsyncTeeWriter, scheduler::Scheduler, util::TableBuilder,
};
mod tee_writer;
@ -202,14 +205,32 @@ async fn spawn_command(
options: ProcessSpawnOptions,
) -> LuaResult<(ExitStatus, Vec<u8>, Vec<u8>)> {
let inherit_stdio = options.inherit_stdio;
let stdin = options.stdin.clone();
let child = options
let mut child = options
.into_command(program, args)
.stdin(Stdio::null())
.stdin(match stdin.is_some() {
true => Stdio::piped(),
false => Stdio::null(),
})
.stdout(Stdio::piped())
.stderr(Stdio::piped())
.spawn()?;
// If the stdin option was provided, we write that to the child
if let Some(stdin) = stdin {
let mut child_stdin = child.stdin.take().unwrap();
let stdin_writer_thread = task::spawn(async move {
let mut tee = AsyncTeeWriter::new(&mut child_stdin);
tee.write_all(stdin.as_bytes()).await.unwrap();
});
stdin_writer_thread
.await
.expect("Tee writer for stdin errored");
}
if inherit_stdio {
pipe_and_inherit_child_process_stdio(child).await
} else {

View file

@ -14,6 +14,7 @@ pub struct ProcessSpawnOptions {
pub(crate) envs: HashMap<String, String>,
pub(crate) shell: Option<String>,
pub(crate) inherit_stdio: bool,
pub(crate) stdin: Option<String>,
}
impl<'lua> FromLua<'lua> for ProcessSpawnOptions {
@ -133,6 +134,20 @@ impl<'lua> FromLua<'lua> for ProcessSpawnOptions {
}
}
/*
If we have stdin contents, we need to pass those to the child process
*/
match value.get("stdin")? {
LuaValue::Nil => this.stdin = None,
LuaValue::String(s) => this.stdin = Some(s.to_string_lossy().to_string()),
value => {
return Err(LuaError::RuntimeError(format!(
"Invalid type for option 'stdin' - expected 'string', got '{}'",
value.type_name()
)))
}
}
Ok(this)
}
}