>>107929109
OK
use std::{
fs::File,
io,
os::fd::{AsRawFd, FromRawFd},
thread::sleep,
time::Duration,
};
use anyhow::bail;
fn main() -> anyhow::Result<()> {
let src = File::open("btrfs/yowch")?;
let dst = unsafe {
let fd = libc::open(
c"btrfs".as_ptr(),
libc::O_TMPFILE | libc::O_RDWR | libc::O_EXCL,
);
if fd == -1 {
bail!("open: {}", io::Error::last_os_error());
}
File::from_raw_fd(fd)
};
unsafe {
if libc::ioctl(dst.as_raw_fd(), libc::FICLONE, src.as_raw_fd()) == -1 {
bail!("ioctl: {}", io::Error::last_os_error());
}
}
drop(src);
let map = unsafe { memmap2::Mmap::map(&dst) }?;
drop(dst);
let string = str::from_utf8(&map)?;
loop {
for ch in string.chars() {
println!("{ch:?}");
}
sleep(Duration::from_secs(1));
}
}
$ truncate -s 114294784 btrfs-test.img
$ mkfs.btrfs btrfs-test.img
$ sudo mount -o loop btrfs-test.img btrfs
$ sudo chown $(whoami):$(whoami) btrfs/
$ testprog
$ echo "Hi" > btrfs/yowch
$ testprog
Hi
Hi
Hi
Hi
[...]
$ ls /proc/1344942/fd/
0@ 1@ 2@
$ printf 'ab\xC2' > btrfs/yowch
The program still keeps printing "Hi" every second, it doesn't observe src's changes.
And I don't think that even if it keeps the fd you're able to modify it? If I remove drop(dst) to keep it open:
$ ls -l /proc/1346365/fd/4
[...] /proc/1346365/fd/4 -> '[...]/btrfs/#261 (deleted)'
$ printf 'ab\xC2' > /proc/1346365/fd/4
warning: An error occurred while redirecting file '/proc/1346365/fd/4'
open: Permission denied