mirror of
https://github.com/lune-org/lune.git
synced 2025-03-03 02:33:36 +00:00
Allow for passing stdin to child (#106)
This commit is contained in:
parent
c43648faec
commit
8865692f1d
4 changed files with 48 additions and 3 deletions
|
@ -7,6 +7,7 @@ use std::{
|
||||||
use dunce::canonicalize;
|
use dunce::canonicalize;
|
||||||
use mlua::prelude::*;
|
use mlua::prelude::*;
|
||||||
use os_str_bytes::RawOsString;
|
use os_str_bytes::RawOsString;
|
||||||
|
use tokio::io::AsyncWriteExt;
|
||||||
|
|
||||||
use crate::lune::{scheduler::Scheduler, util::TableBuilder};
|
use crate::lune::{scheduler::Scheduler, util::TableBuilder};
|
||||||
|
|
||||||
|
@ -199,17 +200,27 @@ async fn process_spawn(
|
||||||
async fn spawn_command(
|
async fn spawn_command(
|
||||||
program: String,
|
program: String,
|
||||||
args: Option<Vec<String>>,
|
args: Option<Vec<String>>,
|
||||||
options: ProcessSpawnOptions,
|
mut options: ProcessSpawnOptions,
|
||||||
) -> LuaResult<(ExitStatus, Vec<u8>, Vec<u8>)> {
|
) -> LuaResult<(ExitStatus, Vec<u8>, Vec<u8>)> {
|
||||||
let inherit_stdio = options.inherit_stdio;
|
let inherit_stdio = options.inherit_stdio;
|
||||||
|
let stdin = options.stdin.take();
|
||||||
|
|
||||||
let child = options
|
let mut child = options
|
||||||
.into_command(program, args)
|
.into_command(program, args)
|
||||||
.stdin(Stdio::null())
|
.stdin(match stdin.is_some() {
|
||||||
|
true => Stdio::piped(),
|
||||||
|
false => Stdio::null(),
|
||||||
|
})
|
||||||
.stdout(Stdio::piped())
|
.stdout(Stdio::piped())
|
||||||
.stderr(Stdio::piped())
|
.stderr(Stdio::piped())
|
||||||
.spawn()?;
|
.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();
|
||||||
|
child_stdin.write_all(&stdin).await.into_lua_err()?;
|
||||||
|
}
|
||||||
|
|
||||||
if inherit_stdio {
|
if inherit_stdio {
|
||||||
pipe_and_inherit_child_process_stdio(child).await
|
pipe_and_inherit_child_process_stdio(child).await
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -14,6 +14,7 @@ pub struct ProcessSpawnOptions {
|
||||||
pub(crate) envs: HashMap<String, String>,
|
pub(crate) envs: HashMap<String, String>,
|
||||||
pub(crate) shell: Option<String>,
|
pub(crate) shell: Option<String>,
|
||||||
pub(crate) inherit_stdio: bool,
|
pub(crate) inherit_stdio: bool,
|
||||||
|
pub(crate) stdin: Option<Vec<u8>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'lua> FromLua<'lua> for ProcessSpawnOptions {
|
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 => {}
|
||||||
|
LuaValue::String(s) => this.stdin = Some(s.as_bytes().to_vec()),
|
||||||
|
value => {
|
||||||
|
return Err(LuaError::RuntimeError(format!(
|
||||||
|
"Invalid type for option 'stdin' - expected 'string', got '{}'",
|
||||||
|
value.type_name()
|
||||||
|
)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Ok(this)
|
Ok(this)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -160,3 +160,20 @@ assert(
|
||||||
echoResult.stdout == (echoMessage .. trailingAddition),
|
echoResult.stdout == (echoMessage .. trailingAddition),
|
||||||
"Inheriting stdio did not return proper output"
|
"Inheriting stdio did not return proper output"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
-- Passing stdin strings should work
|
||||||
|
|
||||||
|
local stdinChild = process.spawn(not IS_WINDOWS and "xargs" or "powershell", {
|
||||||
|
"echo",
|
||||||
|
}, {
|
||||||
|
stdin = echoMessage .. (IS_WINDOWS and "\n\n" or ""),
|
||||||
|
})
|
||||||
|
|
||||||
|
local stdinChildOut = stdinChild.stdout
|
||||||
|
if IS_WINDOWS then
|
||||||
|
stdinChildOut = stdinChildOut:sub(#stdinChildOut - #echoMessage - 1, #stdinChildOut)
|
||||||
|
end
|
||||||
|
assert(
|
||||||
|
stdinChildOut == echoMessage .. trailingAddition,
|
||||||
|
"Stdin passing did not return proper output"
|
||||||
|
)
|
||||||
|
|
|
@ -13,12 +13,14 @@ export type SpawnOptionsStdio = "inherit" | "default"
|
||||||
* `env` - Extra environment variables to give to the process
|
* `env` - Extra environment variables to give to the process
|
||||||
* `shell` - Whether to run in a shell or not - set to `true` to run using the default shell, or a string to run using a specific shell
|
* `shell` - Whether to run in a shell or not - set to `true` to run using the default shell, or a string to run using a specific shell
|
||||||
* `stdio` - How to treat output and error streams from the child process - set to "inherit" to pass output and error streams to the current process
|
* `stdio` - How to treat output and error streams from the child process - set to "inherit" to pass output and error streams to the current process
|
||||||
|
* `stdin` - Optional standard input to pass to spawned child process
|
||||||
]=]
|
]=]
|
||||||
export type SpawnOptions = {
|
export type SpawnOptions = {
|
||||||
cwd: string?,
|
cwd: string?,
|
||||||
env: { [string]: string }?,
|
env: { [string]: string }?,
|
||||||
shell: (boolean | string)?,
|
shell: (boolean | string)?,
|
||||||
stdio: SpawnOptionsStdio?,
|
stdio: SpawnOptionsStdio?,
|
||||||
|
stdin: string?,
|
||||||
}
|
}
|
||||||
|
|
||||||
--[=[
|
--[=[
|
||||||
|
|
Loading…
Add table
Reference in a new issue