From 949d316773906807c1d9a07891411f66d72c62e5 Mon Sep 17 00:00:00 2001 From: Emilie Burgun Date: Mon, 3 Feb 2025 14:26:33 +0100 Subject: [PATCH] Fix realiased streams causing close/1 to leave a dangling stream --- src/machine/streams.rs | 22 +++++++++++++++++++++- src/machine/system_calls.rs | 8 +++++--- 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/src/machine/streams.rs b/src/machine/streams.rs index 3432fadcd..ca348a0ef 100644 --- a/src/machine/streams.rs +++ b/src/machine/streams.rs @@ -640,7 +640,7 @@ impl Stream { } } - pub fn options_mut(&mut self) -> &mut StreamOptions { + pub(super) fn options_mut(&mut self) -> &mut StreamOptions { match self { Stream::Byte(ref mut ptr) => &mut ptr.options, Stream::InputFile(ref mut ptr) => &mut ptr.options, @@ -1946,4 +1946,24 @@ mod test { assert_eq!(results.len(), 1); assert!(results[0].is_ok()); } + + #[test] + #[cfg_attr(miri, ignore)] + fn close_realiased_stream() { + let mut machine = MachineBuilder::new().build(); + + let results = machine + .run_query(r#" + \+ \+ ( + open("README.md", read, S, [alias(readme)]), + open(stream(S), read, _, [alias(another_alias)]), + close(S) + ), + open("README.md", read, _, [alias(readme)]). + "#) + .collect::>(); + + assert_eq!(results.len(), 1); + assert!(results[0].is_ok()); + } } diff --git a/src/machine/system_calls.rs b/src/machine/system_calls.rs index 2b05b8f03..50c28549f 100644 --- a/src/machine/system_calls.rs +++ b/src/machine/system_calls.rs @@ -5162,7 +5162,7 @@ impl Machine { #[inline(always)] pub(crate) fn set_stream_options(&mut self) -> CallResult { - let mut stream = self.machine_st.get_stream_or_alias( + let stream = self.machine_st.get_stream_or_alias( self.machine_st.registers[1], &self.indices, atom!("open"), @@ -5174,10 +5174,12 @@ impl Machine { let reposition = self.machine_st.registers[4]; let stream_type = self.machine_st.registers[5]; - let options = + let new_options = self.machine_st .get_stream_options(alias, eof_action, reposition, stream_type); - *stream.options_mut() = options; + self.indices.update_stream_options(stream, |options| { + *options = new_options; + }); Ok(()) }