diff --git a/Cargo.lock b/Cargo.lock index 9ab1742bfbe..3e101ff0577 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -337,6 +337,7 @@ dependencies = [ "libc", "libgit2-sys", "memchr", + "memfd", "opener", "openssl", "os_info", @@ -2894,6 +2895,15 @@ version = "2.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273" +[[package]] +name = "memfd" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad38eb12aea514a0466ea40a80fd8cc83637065948eb4a426e4aa46261175227" +dependencies = [ + "rustix", +] + [[package]] name = "memmap2" version = "0.9.9" diff --git a/Cargo.toml b/Cargo.toml index 0f807a3d3c9..e80e07f64ed 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -67,6 +67,7 @@ libc = "0.2.177" libgit2-sys = "0.18.2" libloading = "0.8.9" memchr = "2.7.6" +memfd = "0.6.5" miow = "0.6.1" opener = "0.8.3" openssl = "0.10.74" @@ -261,6 +262,9 @@ gix-transport = { version = "0.49.1", features = ["http-client-insecure-credenti same-file.workspace = true snapbox.workspace = true +[target.'cfg(target_os = "linux")'.dev-dependencies] +memfd.workspace = true + [build-dependencies] flate2.workspace = true tar.workspace = true diff --git a/src/cargo/util/context/mod.rs b/src/cargo/util/context/mod.rs index dfe60d5e73e..a7dc7e199f4 100644 --- a/src/cargo/util/context/mod.rs +++ b/src/cargo/util/context/mod.rs @@ -710,7 +710,8 @@ impl GlobalContext { .to_string(), ), ("{workspace-path-hash}", { - let real_path = std::fs::canonicalize(workspace_manifest_path)?; + let real_path = std::fs::canonicalize(workspace_manifest_path) + .unwrap_or_else(|_err| workspace_manifest_path.to_owned()); let hash = crate::util::hex::short_hash(&real_path); format!("{}{}{}", &hash[0..2], std::path::MAIN_SEPARATOR, &hash[2..]) }), diff --git a/tests/testsuite/script/cargo.rs b/tests/testsuite/script/cargo.rs index 6cc590c7c17..1fa8960b27d 100644 --- a/tests/testsuite/script/cargo.rs +++ b/tests/testsuite/script/cargo.rs @@ -1,4 +1,5 @@ use std::fs; +use std::io::Write; use crate::prelude::*; use cargo_test_support::basic_manifest; @@ -2174,3 +2175,40 @@ args: [] "#]]) .run(); } + +#[cargo_test(nightly, reason = "-Zscript is unstable")] +#[cfg(target_os = "linux")] +fn memfd_script() { + use std::os::fd::AsRawFd; + + let fd = memfd::MemfdOptions::new() + .close_on_exec(false) + .create("otkeep-script") + .unwrap(); + let mut file = fd.into_file(); + file.write_all(ECHO_SCRIPT.as_bytes()).unwrap(); + file.flush().unwrap(); + + let raw_fd = file.as_raw_fd(); + + let p = cargo_test_support::project() + .file("echo.rs", ECHO_SCRIPT) + .build(); + + p.cargo(&format!("-Zscript -v /proc/self/fd/{raw_fd}")) + .masquerade_as_nightly_cargo(&["script"]) + .with_stdout_data(str![[r#" +current_exe: [ROOT]/home/.cargo/build/[HASH]/target/debug/package +arg0: /proc/self/fd/[..] +args: [] + +"#]]) + .with_stderr_data(str![[r#" +[WARNING] `package.edition` is unspecified, defaulting to `2024` +[COMPILING] package v0.0.0 (/proc/self/fd/[..]) +[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s +[RUNNING] `[ROOT]/home/.cargo/build/[HASH]/target/debug/package` + +"#]]) + .run(); +}