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
16 changes: 14 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -49,17 +51,27 @@ 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
# 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' }}

- run: cargo-zigbuild test --target x86_64-unknown-linux-gnu.2.17
Expand Down
2 changes: 1 addition & 1 deletion crates/fspy/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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 }

Expand Down
21 changes: 11 additions & 10 deletions crates/fspy/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,29 +55,29 @@ 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",
"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,
),
],
),
(
"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",
"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,
),
],
),
Expand All @@ -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();
Expand Down
44 changes: 44 additions & 0 deletions crates/fspy/tests/shebang.rs
Original file line number Diff line number Diff line change
@@ -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(())
}
5 changes: 5 additions & 0 deletions crates/fspy_preload_unix/src/libc.rs
Original file line number Diff line number Diff line change
@@ -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-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,
namelist: *mut c_void,
Expand All @@ -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,
Expand Down
27 changes: 14 additions & 13 deletions crates/fspy_shared_unix/src/spawn/macos.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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"
};