rust-lang / rust

Empowering everyone to build reliable and efficient software.
https://www.rust-lang.org
Other
95.13k stars 12.27k forks source link

`fs::copy` emits FS events on the source file on macOS #107130

Open wdanilo opened 1 year ago

wdanilo commented 1 year ago

I've got a bizarre behavior here. Here is the code:

#[test]
fn test() {
    std::fs::copy(
        "/Users/wdanilo/Dev/enso/lib/rust/ensogl/pack/js/src/wasm-pack-bundle/wasm-pack-bundle.ts",
        "/tmp/out.txt",
    )
    .unwrap();
}

I'm also running in terminal:

fswatch /Users/wdanilo/Dev/enso/lib/rust/ensogl/pack/js/src/wasm-pack-bundle/wasm-pack-bundle.ts -x -v -t
  1. If /tmp/out.txt EXISTS, then running this test DOES NOT cause fswatch to print anything to the console.
  2. If /tmp/out.txt DOES NOT EXIST, then running the test DOES cause fswatch to print:
notify_events: Notifying events #: 1.
Fri Jan 20 22:16:39 2023 /Users/wdanilo/Dev/enso/lib/rust/ensogl/pack/js/src/wasm-pack-bundle/wasm-pack-bundle.ts IsFile

I discovered that when debugging why my cargo-watch loops forever on building our sources. It seems that when we are copying files, the source file triggers an event, which triggers cargo-watch ...

Please note, that this does not happen when using system's cp command. I'm wondering if this is the correct behavior and if so, it should probably be documented better.

Meta

rustc --version --verbose:

rustc 1.58.1 (db9d1b20b 2022-01-20)
ehuss commented 1 year ago

This is probably just an artifact of using copy-on-write on APFS (via fclonefileat). When the destination does not exist, macOS will do a copy-on-write clone of the file. Presumably that triggers kFSEventStreamEventFlagItemIsFile on the source of the clone. Unfortunately Apple doesn't really document the file-watching API very much.