Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
070467d
use shared memory for fspy ipc
branchseer Oct 16, 2025
5bd8d45
fix merge conflicts
branchseer Oct 16, 2025
612f183
wip
branchseer Oct 17, 2025
e609077
add fspy_test_utils
branchseer Oct 18, 2025
3b31c37
finish ipc channel implementation
branchseer Oct 18, 2025
9adfcc0
implement NativeString for Windows
branchseer Oct 18, 2025
0c1e527
fix compilation errors on Linux
branchseer Oct 18, 2025
4ac3fb4
fix typos
branchseer Oct 18, 2025
63eae72
update usages for new ipc implementation
branchseer Oct 19, 2025
58fa5f6
run vitest-browser-mode test on Linux
branchseer Oct 19, 2025
e880510
write preload library to disk on Linux
branchseer Oct 19, 2025
aef331a
fix cargo check issues
branchseer Oct 19, 2025
7ed6035
fix build error on Windows
branchseer Oct 19, 2025
cb93637
Replace owned ReceiverLock with borrowing OwnedReceiverLockGuard
branchseer Oct 21, 2025
282d9b4
fix typo
branchseer Oct 21, 2025
f8bfdcd
Update crates/fspy_shared/src/ipc/native_str.rs
branchseer Oct 21, 2025
4e3e22d
Update crates/fspy/src/lib.rs
branchseer Oct 21, 2025
25729cc
fix typo
branchseer Oct 21, 2025
b51f282
fix docs
branchseer Oct 21, 2025
af10bf6
add workaround for fix windows fspy
branchseer Oct 21, 2025
4c93327
Update crates/fspy_shared/src/ipc/native_str.rs
branchseer Oct 21, 2025
da02881
Update crates/fspy_shared/src/ipc/channel/shm_io.rs
branchseer Oct 21, 2025
3d078f6
Update crates/fspy_preload_unix/src/client/mod.rs
branchseer Oct 21, 2025
50a15ce
cargo fmt
branchseer Oct 21, 2025
05cbeb6
update lock file
branchseer Oct 23, 2025
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
122 changes: 120 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ fspy_preload_windows = { path = "crates/fspy_preload_windows", artifact = "cdyli
fspy_seccomp_unotify = { path = "crates/fspy_seccomp_unotify" }
fspy_shared = { path = "crates/fspy_shared" }
fspy_shared_unix = { path = "crates/fspy_shared_unix" }
fspy_test_utils = { path = "crates/fspy_test_utils" }
futures = "0.3.31"
futures-core = "0.3.31"
futures-util = "0.3.31"
Expand Down Expand Up @@ -109,6 +110,7 @@ serde_yml = "0.0.12"
serial_test = "3.2.0"
sha1 = "0.10.6"
sha2 = "0.10.9"
shared_memory = "0.12.4"
shell-escape = "0.1.5"
slab = "0.4.9"
smallvec = { version = "2.0.0-alpha.11", features = ["std"] }
Expand Down
2 changes: 1 addition & 1 deletion bench/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ version = "0.1.0"
edition = "2024"

[dependencies]
vite_task = { workspace = true }
vite_path = { workspace = true }
vite_task = { workspace = true }

[dev-dependencies]
criterion = { workspace = true }
Expand Down
6 changes: 2 additions & 4 deletions crates/fspy/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ allocator-api2 = { workspace = true, features = ["alloc"] }
bincode = { workspace = true }
bstr = { workspace = true, default-features = false }
bumpalo = { workspace = true }
const_format = { workspace = true, features = ["fmt"] }
fspy_shared = { workspace = true }
futures-util = { workspace = true }
libc = { workspace = true }
Expand All @@ -18,6 +19,7 @@ slab = { workspace = true }
tempfile = { workspace = true }
tokio = { workspace = true, features = ["net", "process", "io-util", "sync"] }
which = { workspace = true }
xxhash-rust = { workspace = true }

[target.'cfg(target_os = "linux")'.dependencies]
arrayvec = { workspace = true }
Expand All @@ -39,10 +41,6 @@ passfd = { git = "https://github.com/polachok/passfd", features = ["async"] }
[target.'cfg(target_os = "macos")'.dependencies]
phf = { workspace = true }

[target.'cfg(any(target_os = "macos", windows))'.dependencies]
const_format = { workspace = true, features = ["fmt"] }
xxhash-rust = { workspace = true }

[target.'cfg(target_os = "windows")'.dependencies]
fspy_detours_sys = { workspace = true }
fspy_preload_windows = { workspace = true }
Expand Down
3 changes: 2 additions & 1 deletion crates/fspy/examples/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ async fn main() -> io::Result<()> {

let TrackedChild { mut tokio_child, accesses_future } = command.spawn().await?;

let output = tokio_child.wait().await?;

Comment thread
fengmk2 marked this conversation as resolved.
let accesses = accesses_future.await?;

let mut path_count = 0usize;
Expand All @@ -47,7 +49,6 @@ async fn main() -> io::Result<()> {
}
csv_writer.flush().await?;

let output = tokio_child.wait().await?;
eprintln!("\nfspy: {path_count} paths accessed. {output}");
Ok(())
}
1 change: 1 addition & 0 deletions crates/fspy/src/fixture.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ macro_rules! fixture {
pub use fixture;

impl Fixture {
#[cfg(not(target_os = "linux"))]
pub const fn new(name: &'static str, content: &'static [u8], hash: &'static str) -> Self {
Self { name, content, hash }
}
Expand Down
18 changes: 5 additions & 13 deletions crates/fspy/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
#![cfg_attr(target_os = "windows", feature(windows_process_extensions_main_thread_handle))]
#![feature(once_cell_try)]

// Windows and macOS both need to persist the injected DLL/shared library somewhere in the filesystem.
// Linux doesn't need this. Instead we use `memfd_create` to create an in-memory shared library.
#[cfg(not(target_os = "linux"))]
// Persist the injected DLL/shared library somewhere in the filesystem.
mod fixture;

#[cfg(unix)]
Expand All @@ -17,9 +15,7 @@ mod os_impl;
mod arena;
mod command;

#[cfg(not(target_os = "linux"))]
use std::{env::temp_dir, fs::create_dir};
use std::{ffi::OsStr, io, sync::OnceLock};
use std::{env::temp_dir, ffi::OsStr, fs::create_dir, io, sync::OnceLock};

pub use command::Command;
pub use fspy_shared::ipc::{AccessMode, PathAccess};
Expand All @@ -30,23 +26,19 @@ use tokio::process::Child;

pub struct TrackedChild {
pub tokio_child: Child,
pub accesses_future: BoxFuture<'static, io::Result<os_impl::PathAccessIterable>>,
/// This future lazily locks the IPC channel when it's polled.
/// Do not `await` it until the child process has exited.
pub accesses_future: BoxFuture<'static, io::Result<PathAccessIterable>>,
}

pub struct Spy(SpyInner);
impl Spy {
#[cfg(not(target_os = "linux"))]
pub fn new() -> io::Result<Self> {
let tmp_dir = temp_dir().join("fspy");
let _ = create_dir(&tmp_dir);
Ok(Self(SpyInner::init_in(&tmp_dir)?))
}

#[cfg(target_os = "linux")]
pub fn new() -> io::Result<Self> {
Ok(Self(SpyInner::init()?))
}

pub fn global() -> io::Result<&'static Self> {
static GLOBAL_SPY: OnceLock<Spy> = OnceLock::new();
GLOBAL_SPY.get_or_try_init(Self::new)
Expand Down
Loading
Loading