Allow InputLocation::Stdin to specify a file name (#3265)

* Allow filename for InputLocation::StdIn

* clippy

* format code

* rename to input_file

* fix

* changes left out
This commit is contained in:
lazymio 2025-05-23 22:31:41 +08:00 committed by GitHub
parent 71d08f5f04
commit 18d46bed29
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 34 additions and 9 deletions

View File

@ -164,7 +164,7 @@ where
}
Ok(cmd.spawn()?)
}
InputLocation::StdIn => {
InputLocation::StdIn { input_file: _ } => {
let mut handle = self.command.stdin(Stdio::piped()).spawn()?;
let mut stdin = handle.stdin.take().unwrap();
match stdin.write_all(input.target_bytes().as_slice()) {
@ -262,7 +262,7 @@ where
self.args[*argnum] = cstring_input;
}
}
InputLocation::StdIn => {
InputLocation::StdIn { input_file: _ } => {
let (pipe_read, pipe_write) = pipe().unwrap();
write(pipe_write, &input.target_bytes()).unwrap();
dup2(pipe_read.as_raw_fd(), STDIN_FILENO).unwrap();
@ -590,7 +590,14 @@ impl CommandExecutorBuilder {
let mut command = Command::new(program);
match &self.target_inner.input_location {
InputLocation::StdIn => {
InputLocation::StdIn {
input_file: out_file,
} => {
if out_file.is_some() {
return Err(Error::illegal_argument(
"Setting filename for CommandExecutor is not supported!",
));
}
command.stdin(Stdio::piped());
}
InputLocation::File { .. } | InputLocation::Arg { .. } => {

View File

@ -1031,7 +1031,12 @@ where
OT: ObserversTuple<I, S>,
{
let input_file = match &self.target_inner.input_location {
InputLocation::StdIn => InputFile::create(OsString::from(get_unique_std_input_file()))?,
InputLocation::StdIn {
input_file: out_file,
} => match out_file {
Some(out_file) => out_file.clone(),
None => InputFile::create(OsString::from(get_unique_std_input_file()))?,
},
InputLocation::Arg { argnum: _ } => {
return Err(Error::illegal_argument(
"forkserver doesn't support argument mutation",

View File

@ -11,7 +11,7 @@ use crate::fs::{InputFile, get_unique_std_input_file};
/// How to deliver input to an external program
/// `StdIn`: The target reads from stdin
/// `File`: The target reads from the specified [`InputFile`]
#[derive(Debug, Clone, PartialEq, Eq, Default)]
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum InputLocation {
/// Mutate a commandline argument to deliver an input
Arg {
@ -19,8 +19,10 @@ pub enum InputLocation {
argnum: usize,
},
/// Deliver input via `StdIn`
#[default]
StdIn,
StdIn {
/// The alternative input file
input_file: Option<InputFile>,
},
/// Deliver the input via the specified [`InputFile`]
/// You can use specify [`InputFile::create(INPUTFILE_STD)`] to use a default filename.
File {
@ -29,6 +31,12 @@ pub enum InputLocation {
},
}
impl Default for InputLocation {
fn default() -> Self {
Self::StdIn { input_file: None }
}
}
/// The shared inner structs of trait [`StdTargetArgs`]
#[derive(Debug, Clone, Default)]
pub struct StdTargetArgsInner {
@ -82,7 +90,10 @@ pub trait StdTargetArgs: Sized {
/// If use stdin
#[must_use]
fn use_stdin(&self) -> bool {
matches!(self.inner().input_location, InputLocation::StdIn)
matches!(
&self.inner().input_location,
InputLocation::StdIn { input_file: _ }
)
}
/// Set input
@ -114,7 +125,9 @@ pub trait StdTargetArgs: Sized {
assert!(
match &moved.inner().input_location {
InputLocation::File { out_file } => out_file.path.as_path() == path.as_ref(),
InputLocation::StdIn => true,
InputLocation::StdIn { input_file } => input_file
.as_ref()
.is_none_or(|of| of.path.as_path() == path.as_ref()),
InputLocation::Arg { argnum: _ } => false,
},
"Already specified an input file under a different name. This is not supported"