Skip to content

Commit c96c30a

Browse files
committed
test that modifications to the source don't become visible after io::copy
1 parent 932c173 commit c96c30a

File tree

1 file changed

+42
-0
lines changed
  • library/std/src/sys/unix/kernel_copy

1 file changed

+42
-0
lines changed

library/std/src/sys/unix/kernel_copy/tests.rs

+42
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,48 @@ fn copies_append_mode_sink() -> Result<()> {
8383
Ok(())
8484
}
8585

86+
#[test]
87+
fn dont_splice_pipes_from_files() -> Result<()> {
88+
// splicing to a pipe and then modifying the source could lead to changes
89+
// becoming visible in an unexpected order.
90+
91+
use crate::io::SeekFrom;
92+
use crate::os::unix::fs::FileExt;
93+
use crate::process::{ChildStdin, ChildStdout};
94+
use crate::sys_common::FromInner;
95+
96+
let (read_end, write_end) = crate::sys::pipe::anon_pipe()?;
97+
98+
let mut read_end = ChildStdout::from_inner(read_end);
99+
let mut write_end = ChildStdin::from_inner(write_end);
100+
101+
let tmp_path = tmpdir();
102+
let file = tmp_path.join("to_be_modified");
103+
let mut file =
104+
crate::fs::OpenOptions::new().create_new(true).read(true).write(true).open(file)?;
105+
106+
const SZ: usize = libc::PIPE_BUF as usize;
107+
108+
// put data in page cache
109+
let mut buf: [u8; SZ] = [0x01; SZ];
110+
file.write_all(&buf).unwrap();
111+
112+
// copy page into pipe
113+
file.seek(SeekFrom::Start(0)).unwrap();
114+
assert!(io::copy(&mut file, &mut write_end).unwrap() == SZ as u64);
115+
116+
// modify file
117+
buf[0] = 0x02;
118+
file.write_at(&buf, 0).unwrap();
119+
120+
// read from pipe
121+
read_end.read_exact(buf.as_mut_slice()).unwrap();
122+
123+
assert_eq!(buf[0], 0x01, "data in pipe should reflect the original, not later modifications");
124+
125+
Ok(())
126+
}
127+
86128
#[bench]
87129
fn bench_file_to_file_copy(b: &mut test::Bencher) {
88130
const BYTES: usize = 128 * 1024;

0 commit comments

Comments
 (0)