about summary refs log tree commit diff
path: root/library/std/src
diff options
context:
space:
mode:
authorThe 8472 <git@infinite-source.de>2023-04-03 21:09:53 +0200
committerThe 8472 <git@infinite-source.de>2023-04-03 21:10:02 +0200
commitc96c30aeedd753b4e7f4eaa51f7589fed09f40a1 (patch)
treed2b84b30dffe74d797dd81a3697b237bea051b70 /library/std/src
parent932c173ca1b7a79c1005e2d72ddfa505a7bf2cfa (diff)
downloadrust-c96c30aeedd753b4e7f4eaa51f7589fed09f40a1.tar.gz
rust-c96c30aeedd753b4e7f4eaa51f7589fed09f40a1.zip
test that modifications to the source don't become visible after io::copy
Diffstat (limited to 'library/std/src')
-rw-r--r--library/std/src/sys/unix/kernel_copy/tests.rs42
1 files changed, 42 insertions, 0 deletions
diff --git a/library/std/src/sys/unix/kernel_copy/tests.rs b/library/std/src/sys/unix/kernel_copy/tests.rs
index 3fe849e23e2..a524270e3fb 100644
--- a/library/std/src/sys/unix/kernel_copy/tests.rs
+++ b/library/std/src/sys/unix/kernel_copy/tests.rs
@@ -83,6 +83,48 @@ fn copies_append_mode_sink() -> Result<()> {
     Ok(())
 }
 
+#[test]
+fn dont_splice_pipes_from_files() -> Result<()> {
+    // splicing to a pipe and then modifying the source could lead to changes
+    // becoming visible in an unexpected order.
+
+    use crate::io::SeekFrom;
+    use crate::os::unix::fs::FileExt;
+    use crate::process::{ChildStdin, ChildStdout};
+    use crate::sys_common::FromInner;
+
+    let (read_end, write_end) = crate::sys::pipe::anon_pipe()?;
+
+    let mut read_end = ChildStdout::from_inner(read_end);
+    let mut write_end = ChildStdin::from_inner(write_end);
+
+    let tmp_path = tmpdir();
+    let file = tmp_path.join("to_be_modified");
+    let mut file =
+        crate::fs::OpenOptions::new().create_new(true).read(true).write(true).open(file)?;
+
+    const SZ: usize = libc::PIPE_BUF as usize;
+
+    // put data in page cache
+    let mut buf: [u8; SZ] = [0x01; SZ];
+    file.write_all(&buf).unwrap();
+
+    // copy page into pipe
+    file.seek(SeekFrom::Start(0)).unwrap();
+    assert!(io::copy(&mut file, &mut write_end).unwrap() == SZ as u64);
+
+    // modify file
+    buf[0] = 0x02;
+    file.write_at(&buf, 0).unwrap();
+
+    // read from pipe
+    read_end.read_exact(buf.as_mut_slice()).unwrap();
+
+    assert_eq!(buf[0], 0x01, "data in pipe should reflect the original, not later modifications");
+
+    Ok(())
+}
+
 #[bench]
 fn bench_file_to_file_copy(b: &mut test::Bencher) {
     const BYTES: usize = 128 * 1024;