Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .github/ISSUE_TEMPLATE/bug_report.yml
Original file line number Diff line number Diff line change
Expand Up @@ -63,9 +63,9 @@ body:
description: Which backend is being used?
options:
- Unknown/Auto-detected
- inotify (Linux)
- fsevents (macOS)
- kqueue (macOS/BSD)
- inotify (Linux/Android/FreeBSD 15+)
- FSEvents (macOS)
- kqueue (macOS/iOS/BSDs)
- ReadDirectoryChangesW (Windows)
- polling (all platforms)
validations:
Expand Down
20 changes: 14 additions & 6 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -147,15 +147,23 @@ jobs:
if: matrix.rust == 'stable'
run: cargo test --workspace --exclude examples --verbose ${{ matrix.features }} --features tokio

# FreeBSD
# FreeBSD 14 tests the default kqueue backend; FreeBSD 15 tests native inotify.
freebsd:
name: FreeBSD - ${{ matrix.rust }}
name: FreeBSD ${{ matrix.release }} (${{ matrix.backend }}) - ${{ matrix.rust }}
runs-on: ubuntu-latest
needs: quality
strategy:
fail-fast: false
matrix:
rust: [stable, nightly, 1.88]
backend: [kqueue, inotify]
include:
- backend: kqueue
release: "14.4"
cargo_args: ""
- backend: inotify
release: "15.1"
cargo_args: "--features freebsd_inotify"
steps:
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
with:
Expand All @@ -164,7 +172,7 @@ jobs:
- name: Test in FreeBSD VM
uses: vmactions/freebsd-vm@b84ab5559b5a1bb4b8ee2737d2506a16e1737636 # v1.4.8
with:
release: "14.3"
release: ${{ matrix.release }}
envs: "CARGO_TERM_COLOR RUST_BACKTRACE"
usesh: true
prepare: |
Expand All @@ -175,9 +183,9 @@ jobs:
. $HOME/.cargo/env
cargo --version
rustc --version
cargo build --verbose
cargo build --examples --verbose
cargo test --verbose
cargo build --verbose ${{ matrix.cargo_args }}
cargo build --examples --verbose ${{ matrix.cargo_args }}
cargo test --verbose ${{ matrix.cargo_args }}

# Android cross-compilation
android:
Expand Down
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ objc2-core-foundation = { version = "0.3.2", default-features = false }
objc2-core-services = { version = "0.3.2", default-features = false }
futures = "0.3.30"
tokio = { version = "1.49.0", default-features = false, features = ["sync"] }
inotify = { version = "0.11.0", default-features = false }
inotify = { version = "0.11.4", default-features = false }
insta = "1.34.0"
kqueue = "1.2.0"
libc = "0.2.4"
Expand Down
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,10 @@ We follow these MSRV rules:
## Platforms

- Linux / Android: inotify
- macOS: FSEvents or kqueue, see features
- FreeBSD: kqueue (default) or inotify, see features
- macOS: FSEvents (default) or kqueue, see features
- Windows: ReadDirectoryChangesW
- iOS / FreeBSD / NetBSD / OpenBSD / DragonflyBSD: kqueue
- iOS / NetBSD / OpenBSD / DragonflyBSD: kqueue
- All platforms: polling

## License
Expand Down
1 change: 1 addition & 0 deletions notify-debouncer-full/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ crossbeam-channel = ["dep:crossbeam-channel", "notify/crossbeam-channel"]
flume = ["dep:flume", "notify/flume"]
macos_fsevent = ["notify/macos_fsevent"]
macos_kqueue = ["notify/macos_kqueue"]
freebsd_inotify = ["notify/freebsd_inotify"]
serialization-compat-6 = ["notify/serialization-compat-6"]
tokio = ["dep:tokio"]
futures = ["dep:futures"]
Expand Down
17 changes: 9 additions & 8 deletions notify-debouncer-full/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,15 +47,16 @@
//!
//! # Features
//!
//! The following crate features can be turned on or off in your cargo dependency config:
//! The following crate features can be configured in your Cargo dependency:
//!
//! - `serde` passed down to notify-types, off by default
//! - `web-time` passed down to notify-types, off by default
//! - `crossbeam-channel` passed down to notify, off by default
//! - `flume` passed down to notify, off by default
//! - `macos_fsevent` passed down to notify, off by default
//! - `macos_kqueue` passed down to notify, off by default
//! - `serialization-compat-6` passed down to notify, off by default
//! - `macos_fsevent` (default) enables notify's FSEvents backend on macOS
//! - `freebsd_inotify` enables notify's native inotify backend on FreeBSD 15+
//! - `macos_kqueue` enables notify's kqueue backend on macOS
//! - `serde` enables serialization support in notify-types
//! - `web-time` uses `web_time::Instant` for debounced events
//! - `crossbeam-channel`, `flume`, `futures`, and `tokio` enable the corresponding
//! channel senders as event handlers
//! - `serialization-compat-6` restores notify 6 serialization behavior
//!
//! # Caveats
//!
Expand Down
1 change: 1 addition & 0 deletions notify-debouncer-mini/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ crossbeam-channel = ["dep:crossbeam-channel", "notify/crossbeam-channel"]
flume = ["dep:flume", "notify/flume"]
macos_fsevent = ["notify/macos_fsevent"]
macos_kqueue = ["notify/macos_kqueue"]
freebsd_inotify = ["notify/freebsd_inotify"]
serialization-compat-6 = ["notify/serialization-compat-6"]
tokio = ["dep:tokio"]
futures = ["dep:futures"]
Expand Down
15 changes: 8 additions & 7 deletions notify-debouncer-mini/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,14 +43,15 @@
//!
//! # Features
//!
//! The following crate features can be turned on or off in your cargo dependency config:
//! The following crate features can be configured in your Cargo dependency:
//!
//! - `serde` passed down to notify-types, off by default
//! - `crossbeam-channel` passed down to notify, off by default
//! - `flume` passed down to notify, off by default
//! - `macos_fsevent` passed down to notify, off by default
//! - `macos_kqueue` passed down to notify, off by default
//! - `serialization-compat-6` passed down to notify, off by default
//! - `macos_fsevent` (default) enables notify's FSEvents backend on macOS
//! - `freebsd_inotify` enables notify's native inotify backend on FreeBSD 15+
//! - `macos_kqueue` enables notify's kqueue backend on macOS
//! - `serde` enables serialization support in notify-types
//! - `crossbeam-channel`, `flume`, `futures`, and `tokio` enable the corresponding
//! channel senders as event handlers
//! - `serialization-compat-6` restores notify 6 serialization behavior
//!
//! # Caveats
//!
Expand Down
2 changes: 2 additions & 0 deletions notify/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

## unreleased

- FEATURE: [FreeBSD] add native inotify support on FreeBSD 15.0+ behind the `freebsd_inotify` feature. kqueue remains the default backend.
- DEPS: bump `inotify` to 0.11.4 for native FreeBSD support
- FEATURE: [macOS] add `Config::with_fsevent_latency` to configure FSEvents stream latency [#930]
- FIX: [windows] emit a Remove event when a watched directory is deleted, matching inotify and FSEvents
- FIX: [windows] surface `ReadDirectoryChangesW` read-start failures [#935]
Expand Down
10 changes: 9 additions & 1 deletion notify/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ default = ["macos_fsevent"]
serde = ["notify-types/serde"]
macos_kqueue = ["kqueue", "mio"]
macos_fsevent = ["objc2-core-foundation", "objc2-core-services"]
# Opt-in native inotify backend for FreeBSD 15+.
freebsd_inotify = ["dep:inotify"]
serialization-compat-6 = ["notify-types/serialization-compat-6"]
tokio = ["dep:tokio"]
futures = ["dep:futures"]
Expand Down Expand Up @@ -70,7 +72,13 @@ windows-sys = { workspace = true, features = [
"Win32_System_IO",
] }

[target.'cfg(any(target_os="freebsd", target_os="openbsd", target_os = "netbsd", target_os = "dragonfly", target_os = "ios"))'.dependencies]
# Keep kqueue available when the inotify backend is enabled.
[target.'cfg(target_os="freebsd")'.dependencies]
inotify = { workspace = true, default-features = false, optional = true }
kqueue.workspace = true
mio.workspace = true

[target.'cfg(any(target_os="openbsd", target_os = "netbsd", target_os = "dragonfly", target_os = "ios"))'.dependencies]
kqueue.workspace = true
mio.workspace = true

Expand Down
7 changes: 5 additions & 2 deletions notify/src/inotify.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//! Watcher implementation for the inotify Linux API
//! Inotify watcher implementation for Linux, Android, and FreeBSD 15.0+.
//!
//! The inotify API provides a mechanism for monitoring filesystem events. Inotify can be used to
//! monitor individual files, or to monitor directories. When a directory is monitored, inotify
Expand Down Expand Up @@ -1693,7 +1693,8 @@ mod tests {
break event;
}
};
assert_eq!(event, expected(&path).modify_data_any());
// Linux and FreeBSD classify this modification differently.
assert_eq!(event, expected(&path).modify());
}

#[test]
Expand Down Expand Up @@ -1779,7 +1780,9 @@ mod tests {
]);
}

// FreeBSD reports writes through any hard link to the watched inode.
#[test]
#[cfg(not(target_os = "freebsd"))]
fn write_to_a_hardlink_pointed_to_the_file_in_the_watched_dir_doesnt_trigger_an_event() {
let tmpdir = testdir();
let (mut watcher, mut rx) = watcher();
Expand Down
41 changes: 32 additions & 9 deletions notify/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,9 @@
//! List of compilation features, see below for details
//!
//! - `serde` for serialization of events
//! - `macos_fsevent` enabled by default, for fsevent backend on macos
//! - `macos_kqueue` for kqueue backend on macos
//! - `macos_fsevent` (default) for the FSEvents backend on macOS
//! - `macos_kqueue` for the kqueue backend on macOS
//! - `freebsd_inotify` for native inotify on FreeBSD 15.0+
//! - `serialization-compat-6` restores the serialization behavior of notify 6, off by default
//!
//! ### Serde
Expand Down Expand Up @@ -181,23 +182,37 @@ use std::path::{Path, PathBuf};
pub(crate) type StdResult<T, E> = std::result::Result<T, E>;
pub(crate) type Receiver<T> = std::sync::mpsc::Receiver<T>;
pub(crate) type Sender<T> = std::sync::mpsc::Sender<T>;
#[cfg(any(target_os = "linux", target_os = "android", target_os = "windows"))]
#[cfg(any(
target_os = "linux",
target_os = "android",
all(target_os = "freebsd", feature = "freebsd_inotify"),
target_os = "windows",
))]
pub(crate) type BoundSender<T> = std::sync::mpsc::SyncSender<T>;

#[inline]
pub(crate) fn unbounded<T>() -> (Sender<T>, Receiver<T>) {
std::sync::mpsc::channel()
}

#[cfg(any(target_os = "linux", target_os = "android", target_os = "windows"))]
#[cfg(any(
target_os = "linux",
target_os = "android",
all(target_os = "freebsd", feature = "freebsd_inotify"),
target_os = "windows",
))]
#[inline]
pub(crate) fn bounded<T>(cap: usize) -> (BoundSender<T>, Receiver<T>) {
std::sync::mpsc::sync_channel(cap)
}

#[cfg(all(target_os = "macos", not(feature = "macos_kqueue")))]
pub use crate::fsevent::FsEventWatcher;
#[cfg(any(target_os = "linux", target_os = "android"))]
#[cfg(any(
target_os = "linux",
target_os = "android",
all(target_os = "freebsd", feature = "freebsd_inotify"),
))]
pub use crate::inotify::INotifyWatcher;
#[cfg(any(
target_os = "freebsd",
Expand All @@ -215,7 +230,11 @@ pub use windows::ReadDirectoryChangesWatcher;

#[cfg(all(target_os = "macos", not(feature = "macos_kqueue")))]
pub mod fsevent;
#[cfg(any(target_os = "linux", target_os = "android"))]
#[cfg(any(
target_os = "linux",
target_os = "android",
all(target_os = "freebsd", feature = "freebsd_inotify"),
))]
pub mod inotify;
#[cfg(any(
target_os = "freebsd",
Expand Down Expand Up @@ -309,7 +328,7 @@ impl EventHandler for std::sync::mpsc::Sender<Result<Event>> {
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[non_exhaustive]
pub enum WatcherKind {
/// inotify backend (linux)
/// Inotify backend (Linux, Android, and FreeBSD 15+ with `freebsd_inotify`)
Inotify,
/// FS-Event backend (mac)
Fsevent,
Expand Down Expand Up @@ -465,7 +484,11 @@ pub trait Watcher {
}

/// The recommended [`Watcher`] implementation for the current platform
#[cfg(any(target_os = "linux", target_os = "android"))]
#[cfg(any(
target_os = "linux",
target_os = "android",
all(target_os = "freebsd", feature = "freebsd_inotify"),
))]
pub type RecommendedWatcher = INotifyWatcher;
/// The recommended [`Watcher`] implementation for the current platform
#[cfg(all(target_os = "macos", not(feature = "macos_kqueue")))]
Expand All @@ -475,7 +498,7 @@ pub type RecommendedWatcher = FsEventWatcher;
pub type RecommendedWatcher = ReadDirectoryChangesWatcher;
/// The recommended [`Watcher`] implementation for the current platform
#[cfg(any(
target_os = "freebsd",
all(target_os = "freebsd", not(feature = "freebsd_inotify")),
target_os = "openbsd",
target_os = "netbsd",
target_os = "dragonfly",
Expand Down