From 1cf7dba6cb9ac2d0ad3a37d1721bc582d93c91f0 Mon Sep 17 00:00:00 2001 From: branchseer Date: Tue, 9 Dec 2025 22:08:31 +0800 Subject: [PATCH 1/7] test: test fspy on shebang scripts --- crates/fspy/Cargo.toml | 2 +- crates/fspy/build.rs | 9 ++++---- crates/fspy/tests/shebang.rs | 44 ++++++++++++++++++++++++++++++++++++ 3 files changed, 50 insertions(+), 5 deletions(-) create mode 100644 crates/fspy/tests/shebang.rs diff --git a/crates/fspy/Cargo.toml b/crates/fspy/Cargo.toml index 5703ef4b..04e8b131 100644 --- a/crates/fspy/Cargo.toml +++ b/crates/fspy/Cargo.toml @@ -19,7 +19,7 @@ ouroboros = { workspace = true } rand = { workspace = true } tempfile = { workspace = true } thiserror = { workspace = true } -tokio = { workspace = true, features = ["net", "process", "io-util", "sync"] } +tokio = { workspace = true, features = ["net", "process", "io-util", "sync", "rt"] } which = { workspace = true, features = ["tracing"] } xxhash-rust = { workspace = true } diff --git a/crates/fspy/build.rs b/crates/fspy/build.rs index 5a612e40..ac413ee3 100644 --- a/crates/fspy/build.rs +++ b/crates/fspy/build.rs @@ -55,9 +55,9 @@ const MACOS_BINARY_DOWNLOADS: &[(&str, &[(&str, &str, u128)])] = &[ "aarch64", &[ ( - "https://github.com/branchseer/oils-for-unix-binaries/releases/download/0.29.0-manual/oils-for-unix-0.29.0-aarch64-apple-darwin.tar.gz", + "https://github.com/branchseer/oils-for-unix-build/releases/download/oils-for-unix-0.37.0/oils-for-unix-0.37.0-darwin-arm64.tar.gz", "oils-for-unix", - 149_945_237_112_824_769_531_360_595_981_178_091_193, + 282073174065923237490435663309538399576, ), ( "https://github.com/uutils/coreutils/releases/download/0.1.0/coreutils-0.1.0-aarch64-apple-darwin.tar.gz", @@ -70,9 +70,9 @@ const MACOS_BINARY_DOWNLOADS: &[(&str, &[(&str, &str, u128)])] = &[ "x86_64", &[ ( - "https://github.com/branchseer/oils-for-unix-binaries/releases/download/0.29.0-manual/oils-for-unix-0.29.0-x86_64-apple-darwin.tar.gz", + "https://github.com/branchseer/oils-for-unix-build/releases/download/oils-for-unix-0.37.0/oils-for-unix-0.37.0-darwin-x86_64.tar.gz", "oils-for-unix", - 286_203_014_616_009_968_685_843_701_528_129_413_859, + 142673558272427867831039361796426010330, ), ( "https://github.com/uutils/coreutils/releases/download/0.1.0/coreutils-0.1.0-x86_64-apple-darwin.tar.gz", @@ -87,6 +87,7 @@ fn fetch_macos_binaries() -> anyhow::Result<()> { if env::var("CARGO_CFG_TARGET_OS").unwrap() != "macos" { return Ok(()); } + let out_dir = current_dir().unwrap().join(Path::new(&std::env::var_os("OUT_DIR").unwrap())); let target_arch = env::var("CARGO_CFG_TARGET_ARCH").unwrap(); diff --git a/crates/fspy/tests/shebang.rs b/crates/fspy/tests/shebang.rs new file mode 100644 index 00000000..52f2d8d7 --- /dev/null +++ b/crates/fspy/tests/shebang.rs @@ -0,0 +1,44 @@ +#![cfg(unix)] + +mod test_utils; + +use std::{ + os::unix::fs::PermissionsExt, + path::Path, + process::{Command, Stdio}, +}; + +use fspy::AccessMode; +use test_log::test; +use test_utils::assert_contains; +use tokio::fs; + +#[test(tokio::test)] +async fn spawn_sh_shebang() -> anyhow::Result<()> { + let tmp_dir = tempfile::TempDir::new()?; + + let shebang_script_path = tmp_dir.path().join("fspy_test_shebang_script.sh"); + let shebang_script_path = shebang_script_path.into_os_string().into_string().unwrap(); + + fs::write(&shebang_script_path, "#!/bin/sh\ncat hello\n").await?; + + let mut perms = fs::metadata(&shebang_script_path).await?.permissions(); + perms.set_mode(0o755); + fs::set_permissions(&shebang_script_path, perms).await?; + + let accesses = track_child!(shebang_script_path.clone(), |shebang_script_path: String| { + let _ignored = Command::new(&shebang_script_path) + .current_dir("/") + .stdin(Stdio::null()) + .stdout(Stdio::piped()) + .stderr(Stdio::piped()) + .status() + .expect("Failed to execute shebang script"); + }) + .await?; + + assert_contains(&accesses, Path::new(&shebang_script_path), AccessMode::READ); + assert_contains(&accesses, Path::new("/hello"), AccessMode::READ); + + Ok(()) +} From bda7a05b8a1fd8ceaedad37ce73c4e929400a81f Mon Sep 17 00:00:00 2001 From: branchseer Date: Tue, 9 Dec 2025 22:13:08 +0800 Subject: [PATCH 2/7] test macos x86_64 --- .github/workflows/ci.yml | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ff0ddb5c..3aee0750 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -37,6 +37,8 @@ jobs: target: x86_64-pc-windows-msvc - os: namespace-profile-mac-default target: aarch64-apple-darwin + - os: namespace-profile-mac-default + target: x86_64-apple-darwin runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 @@ -49,17 +51,19 @@ jobs: save-cache: ${{ github.ref_name == 'main' }} cache-key: test + - run: rustup target add ${{ matrix.target }} + - run: rustup target add x86_64-unknown-linux-musl if: ${{ matrix.os == 'ubuntu-latest' }} - run: pip install cargo-zigbuild if: ${{ matrix.os == 'ubuntu-latest' }} - - run: cargo check --all-targets --all-features + - run: cargo check --all-targets --all-features --target ${{ matrix.target }} env: RUSTFLAGS: '-D warnings --cfg tokio_unstable' # also update .cargo/config.toml - - run: cargo test + - run: cargo test --target ${{ matrix.target }} if: ${{ matrix.os != 'ubuntu-latest' }} - run: cargo-zigbuild test --target x86_64-unknown-linux-gnu.2.17 From 5a1add335f4e3e235d7a2ade31fb035961e21023 Mon Sep 17 00:00:00 2001 From: branchseer Date: Tue, 9 Dec 2025 22:18:35 +0800 Subject: [PATCH 3/7] bump coreutils version --- crates/fspy/build.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/crates/fspy/build.rs b/crates/fspy/build.rs index ac413ee3..5aacab39 100644 --- a/crates/fspy/build.rs +++ b/crates/fspy/build.rs @@ -60,9 +60,9 @@ const MACOS_BINARY_DOWNLOADS: &[(&str, &[(&str, &str, u128)])] = &[ 282073174065923237490435663309538399576, ), ( - "https://github.com/uutils/coreutils/releases/download/0.1.0/coreutils-0.1.0-aarch64-apple-darwin.tar.gz", - "coreutils-0.1.0-aarch64-apple-darwin/coreutils", - 255_656_813_290_649_147_736_009_964_224_176_006_890, + "https://github.com/uutils/coreutils/releases/download/0.4.0/coreutils-0.4.0-aarch64-apple-darwin.tar.gz", + "coreutils-0.4.0-aarch64-apple-darwin/coreutils", + 35998406686137668997937014088186935383, ), ], ), @@ -75,9 +75,9 @@ const MACOS_BINARY_DOWNLOADS: &[(&str, &[(&str, &str, u128)])] = &[ 142673558272427867831039361796426010330, ), ( - "https://github.com/uutils/coreutils/releases/download/0.1.0/coreutils-0.1.0-x86_64-apple-darwin.tar.gz", - "coreutils-0.1.0-x86_64-apple-darwin/coreutils", - 75_344_743_234_387_926_348_628_744_659_874_018_387, + "https://github.com/uutils/coreutils/releases/download/0.4.0/coreutils-0.4.0-x86_64-apple-darwin.tar.gz", + "coreutils-0.4.0-x86_64-apple-darwin/coreutils", + 120898281113671104995723556995187526689, ), ], ), From 15186a008a0bf2feffaffadb3cf98347c54f4465 Mon Sep 17 00:00:00 2001 From: branchseer Date: Tue, 9 Dec 2025 22:26:54 +0800 Subject: [PATCH 4/7] setup x86_64 node for x86_64-apple-darwin --- .github/workflows/ci.yml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3aee0750..ce87e1ad 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -63,6 +63,14 @@ jobs: env: RUSTFLAGS: '-D warnings --cfg tokio_unstable' # also update .cargo/config.toml + # fspy contains tests for Node.js fs accesses. + # use x86_64 node for x86_64-apple-darwin target. + - uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f # v6.1.0 + with: + node-version-file: .node-version + architecture: x64 + if: ${{ matrix.target == 'x86_64-apple-darwin' }} + - run: cargo test --target ${{ matrix.target }} if: ${{ matrix.os != 'ubuntu-latest' }} From 9502d1df48873f65b277bc8ef8902a44edef92e6 Mon Sep 17 00:00:00 2001 From: branchseer Date: Tue, 9 Dec 2025 22:43:26 +0800 Subject: [PATCH 5/7] update COREUTILS_FUNCTIONS --- crates/fspy_shared_unix/src/spawn/macos.rs | 27 +++++++++++----------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/crates/fspy_shared_unix/src/spawn/macos.rs b/crates/fspy_shared_unix/src/spawn/macos.rs index fe487374..a33b27c0 100644 --- a/crates/fspy_shared_unix/src/spawn/macos.rs +++ b/crates/fspy_shared_unix/src/spawn/macos.rs @@ -75,17 +75,18 @@ pub fn handle_exec( } pub static COREUTILS_FUNCTIONS: Set<&'static [u8]> = phf_set! { - b"[", b"arch", b"b2sum", b"b3sum", b"base32", b"base64", b"basename", b"basenc", - b"cat", b"chgrp", b"chmod", b"chown", b"chroot", b"cksum", b"comm", b"cp", b"csplit", - b"cut", b"date", b"dd", b"df", b"dir", b"dircolors", b"dirname", b"du", b"echo", b"env", - b"expand", b"expr", b"factor", b"false", b"fmt", b"fold", b"groups", b"hashsum", b"head", - b"hostid", b"hostname", b"id", b"install", b"join", b"kill", b"link", b"ln", b"logname", - b"ls", b"md5sum", b"mkdir", b"mkfifo", b"mknod", b"mktemp", b"more", b"mv", b"nice", b"nl", - b"nohup", b"nproc", b"numfmt", b"od", b"paste", b"pathchk", b"pinky", b"pr", b"printenv", - b"printf", b"ptx", b"pwd", b"readlink", b"realpath", b"rm", b"rmdir", b"seq", b"sha1sum", - b"sha224sum", b"sha256sum", b"sha3-224sum", b"sha3-256sum", b"sha3-384sum", b"sha3-512sum", - b"sha384sum", b"sha3sum", b"sha512sum", b"shake128sum", b"shake256sum", b"shred", b"shuf", - b"sleep", b"sort", b"split", b"stat", b"stdbuf", b"stty", b"sum", b"sync", b"tac", b"tail", - b"tee", b"test", b"timeout", b"touch", b"tr", b"true", b"truncate", b"tsort", b"tty", b"uname", - b"unexpand", b"uniq", b"unlink", b"uptime", b"users", b"vdir", b"wc", b"who", b"whoami", b"yes", + b"[", b"arch", b"b2sum", b"base32", b"base64", b"basename", b"basenc", b"cat", + b"chgrp", b"chmod", b"chown", b"chroot", b"cksum", b"comm", b"cp", b"csplit", + b"cut", b"date", b"dd", b"df", b"dir", b"dircolors", b"dirname", b"du", b"echo", + b"env", b"expand", b"expr", b"factor", b"false", b"fmt", b"fold", b"groups", + b"hashsum", b"head", b"hostid", b"hostname", b"id", b"install", b"join", b"kill", + b"link", b"ln", b"logname", b"ls", b"md5sum", b"mkdir", b"mkfifo", b"mknod", + b"mktemp", b"more", b"mv", b"nice", b"nl", b"nohup", b"nproc", b"numfmt", b"od", + b"paste", b"pathchk", b"pinky", b"pr", b"printenv", b"printf", b"ptx", b"pwd", + b"readlink", b"realpath", b"rm", b"rmdir", b"seq", b"sha1sum", b"sha224sum", + b"sha256sum", b"sha384sum", b"sha512sum", b"shred", b"shuf", b"sleep", b"sort", + b"split", b"stat", b"stdbuf", b"stty", b"sum", b"sync", b"tac", b"tail", b"tee", + b"test", b"timeout", b"touch", b"tr", b"true", b"truncate", b"tsort", b"tty", + b"uname", b"unexpand", b"uniq", b"unlink", b"uptime", b"users", b"vdir", b"wc", + b"who", b"whoami", b"yes" }; From 5babcf539bd761e7dd3996858f83a3451d1f945e Mon Sep 17 00:00:00 2001 From: branchseer Date: Wed, 10 Dec 2025 00:14:07 +0800 Subject: [PATCH 6/7] fix: use $INODE64 symbol suffix for scandir on macOS x86_64 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On macOS x86_64, directory functions like scandir use the $INODE64 symbol suffix for 64-bit inode support. On arm64, 64-bit inodes are the only option so no suffix is needed. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- crates/fspy_preload_unix/src/libc.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/crates/fspy_preload_unix/src/libc.rs b/crates/fspy_preload_unix/src/libc.rs index 3dc9570f..adfe5bb1 100644 --- a/crates/fspy_preload_unix/src/libc.rs +++ b/crates/fspy_preload_unix/src/libc.rs @@ -1,6 +1,10 @@ pub use libc::*; unsafe extern "C" { + // On macOS x86_64, directory functions use $INODE64 symbol suffix for 64-bit inode support. + // On arm64, 64-bit inodes are the only option so no suffix is needed. + // https://github.com/apple-oss-distributions/Libc/blob/baf2629e4b4b9bc64382d12ef70c8e696aa62494/include/dirent.h#L188 + #[cfg_attr(all(target_os = "macos", target_arch = "x86_64"), link_name = "scandir$INODE64")] pub unsafe fn scandir( dirname: *const c_char, namelist: *mut c_void, @@ -9,6 +13,7 @@ unsafe extern "C" { ) -> c_int; #[cfg(target_os = "macos")] + #[cfg_attr(target_arch = "x86_64", link_name = "scandir_b$INODE64")] pub unsafe fn scandir_b( dirname: *const c_char, namelist: *mut c_void, From c9266c24c4aa8e283f234c6a4e96631912e80544 Mon Sep 17 00:00:00 2001 From: branchseer Date: Wed, 10 Dec 2025 00:14:59 +0800 Subject: [PATCH 7/7] fix link --- crates/fspy_preload_unix/src/libc.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/fspy_preload_unix/src/libc.rs b/crates/fspy_preload_unix/src/libc.rs index adfe5bb1..8d5d2d0a 100644 --- a/crates/fspy_preload_unix/src/libc.rs +++ b/crates/fspy_preload_unix/src/libc.rs @@ -3,7 +3,7 @@ pub use libc::*; unsafe extern "C" { // On macOS x86_64, directory functions use $INODE64 symbol suffix for 64-bit inode support. // On arm64, 64-bit inodes are the only option so no suffix is needed. - // https://github.com/apple-oss-distributions/Libc/blob/baf2629e4b4b9bc64382d12ef70c8e696aa62494/include/dirent.h#L188 + // https://github.com/apple-open-source-mirror/Libc/blob/5e566be7a7047360adfb35ffc44c6a019a854bea/include/dirent.h#L198 #[cfg_attr(all(target_os = "macos", target_arch = "x86_64"), link_name = "scandir$INODE64")] pub unsafe fn scandir( dirname: *const c_char,