fix exit_code handling when running a scripts with ctrlc (#11466)

# Description
Fixes: #11394

When run `^sleep 3` we have an `exit_code ListStream`, and when we press
ctrl-c, this `ListStream` will return None. But it's not expected,
because `exit_code` sender in `run_external` always send an exit code
out.

This pr is trying to fix the issue by introducing a `first_guard` into
ListStream, it will always generate a value from underlying stream if
`first_guard` is true, so it's guarantee to have at least one value to
return.

And the pr also do a little refactor, which makes use of
`ListStream::from_stream` rather than construct it manually.

# User-Facing Changes
## Before
```
> nu -c "^sleep 3"  # press ctrl-c
> echo $env.LAST_EXIT_CODE
0
```

## After
```
> nu -c "^sleep 3"  # press ctrl-c
> echo $env.LAST_EXIT_CODE
255
```

# Tests + Formatting
None, sorry that I don't think it's easy to test the ctrlc behavior.

# After Submitting
None
This commit is contained in:
WindSoilder
2024-01-30 22:41:14 +08:00
committed by GitHub
parent 4e0a65c822
commit c371d1a535
3 changed files with 37 additions and 42 deletions

View File

@ -140,30 +140,30 @@ pub fn run_seq(
if !contains_decimals {
// integers only
Ok(PipelineData::ListStream(
nu_protocol::ListStream {
stream: Box::new(IntSeq {
nu_protocol::ListStream::from_stream(
IntSeq {
count: first as i64,
step: step as i64,
last: last as i64,
span,
}),
ctrlc: engine_state.ctrlc.clone(),
},
},
engine_state.ctrlc.clone(),
),
None,
))
} else {
// floats
Ok(PipelineData::ListStream(
nu_protocol::ListStream {
stream: Box::new(FloatSeq {
nu_protocol::ListStream::from_stream(
FloatSeq {
first,
step,
last,
index: 0,
span,
}),
ctrlc: engine_state.ctrlc.clone(),
},
},
engine_state.ctrlc.clone(),
),
None,
))
}