Fix try printing when it is not the last pipeline element (#13992)

# Description

Fixes #13991. This was done by more clearly separating the case when a
pipeline is drained vs when it is being written (to a file).

I also added an `OutDest::Print` case which might not be strictly
necessary, but is a helpful addition.

# User-Facing Changes

Bug fix.

# Tests + Formatting

Added a test.

# After Submitting

There are still a few redirection bugs that I found, but they require
larger code changes, so I'll leave them until after the release.
This commit is contained in:
Ian Manske
2024-10-11 23:37:10 -07:00
committed by GitHub
parent 0e3a8c552c
commit de08b68ba8
14 changed files with 127 additions and 194 deletions

View File

@ -322,13 +322,13 @@ fn eval_instruction<D: DebugContext>(
let data = ctx.take_reg(*src);
drain(ctx, data)
}
Instruction::WriteToOutDests { src } => {
Instruction::DrainIfEnd { src } => {
let data = ctx.take_reg(*src);
let res = {
let stack = &mut ctx
.stack
.push_redirection(ctx.redirect_out.clone(), ctx.redirect_err.clone());
data.write_to_out_dests(ctx.engine_state, stack)?
data.drain_to_out_dests(ctx.engine_state, stack)?
};
ctx.put_reg(*src, res);
Ok(Continue)
@ -507,14 +507,19 @@ fn eval_instruction<D: DebugContext>(
msg: format!("Tried to write to file #{file_num}, but it is not open"),
span: Some(*span),
})?;
let result = {
let mut stack = ctx
.stack
.push_redirection(Some(Redirection::File(file)), None);
src.write_to_out_dests(ctx.engine_state, &mut stack)?
let is_external = if let PipelineData::ByteStream(stream, ..) = &src {
matches!(stream.source(), ByteStreamSource::Child(..))
} else {
false
};
// Abort execution if there's an exit code from a failed external
drain(ctx, result)
if let Err(err) = src.write_to(file.as_ref()) {
if is_external {
ctx.stack.set_last_error(&err);
}
Err(err)?
} else {
Ok(Continue)
}
}
Instruction::CloseFile { file_num } => {
if ctx.files[*file_num as usize].take().is_some() {
@ -1421,6 +1426,7 @@ fn eval_redirection(
RedirectMode::Value => Ok(Some(Redirection::Pipe(OutDest::Value))),
RedirectMode::Null => Ok(Some(Redirection::Pipe(OutDest::Null))),
RedirectMode::Inherit => Ok(Some(Redirection::Pipe(OutDest::Inherit))),
RedirectMode::Print => Ok(Some(Redirection::Pipe(OutDest::Print))),
RedirectMode::File { file_num } => {
let file = ctx
.files