]> Repositorios git - scryer-prolog.git/commitdiff
Fix realiased streams causing close/1 to leave a dangling stream
authorEmilie Burgun <[email protected]>
Mon, 3 Feb 2025 13:26:33 +0000 (14:26 +0100)
committerEmilie Burgun <[email protected]>
Thu, 6 Feb 2025 22:00:00 +0000 (23:00 +0100)
src/machine/streams.rs
src/machine/system_calls.rs

index 3432fadcd1a470f457d9891f3a8565187876a7b4..ca348a0ef172eb1d99ed2156be661025336e616e 100644 (file)
@@ -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::<Vec<_>>();
+
+        assert_eq!(results.len(), 1);
+        assert!(results[0].is_ok());
+    }
 }
index 2b05b8f03495ed8064cd22ed6eda2a4aa0926810..50c28549fec49d43e5c32fdcfd92366bdae18897 100644 (file)
@@ -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(())
     }