Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 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
47 changes: 6 additions & 41 deletions m4/tests/integration_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,6 @@ use std::os::unix::ffi::OsStrExt;
use std::os::unix::process::ExitStatusExt;
use std::path::Path;
use std::process::ExitStatus;
use std::sync::Once;

static BUILD_ONCE: Once = Once::new();

fn init() {
let _ = env_logger::builder()
Expand Down Expand Up @@ -74,54 +71,22 @@ fn run_command(input: &Path) -> std::process::Output {
}
b"args" => {
let args = input_string;

// Get the workspace root from CARGO_MANIFEST_DIR (set at compile time)
// CARGO_MANIFEST_DIR points to the m4 crate directory, so parent is workspace root
let manifest_dir = env!("CARGO_MANIFEST_DIR");
let workspace_root = std::path::Path::new(manifest_dir)
.parent()
.expect("m4 crate should have parent directory");
let _cargo_build_output = std::process::Command::new("cargo")
.arg("build")
.output()
.unwrap();

// Determine the target directory - cargo-llvm-cov uses a custom target dir
let target_dir = std::env::var("CARGO_TARGET_DIR")
.or_else(|_| std::env::var("CARGO_LLVM_COV_TARGET_DIR"))
.unwrap_or_else(|_| String::from("target"));
let m4_path = format!("../{}/debug/m4", target_dir);

// Check for release binary first (if running release tests), then debug
let release_path = workspace_root.join(&target_dir).join("release").join("m4");
let debug_path = workspace_root.join(&target_dir).join("debug").join("m4");

let m4_path = if release_path.exists() {
release_path
} else {
// Build debug binary if release doesn't exist
// Use Once to ensure cargo build runs only once, avoiding race conditions
// when multiple .args tests run in parallel
BUILD_ONCE.call_once(|| {
let cargo_build_output = std::process::Command::new("cargo")
.arg("build")
.arg("-p")
.arg("posixutils-m4")
.current_dir(workspace_root)
.output()
.unwrap();
if !cargo_build_output.status.success() {
panic!(
"cargo build failed: {}",
String::from_utf8_lossy(&cargo_build_output.stderr)
);
}
});
debug_path
};

log::info!("Using m4 binary at: {}", m4_path.display());
log::info!("RUST_LOG is ignored for this test because it interferes with output");
let output = std::process::Command::new("sh")
.env("RUST_LOG", "") // Disable rust log output because it interferes with the test.
.arg("-c")
.arg(format!("{} {args}", m4_path.display()))
.current_dir(manifest_dir)
.arg(format!("{m4_path} {args}"))
.output()
.unwrap();

Expand Down
10 changes: 5 additions & 5 deletions misc/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
//

use std::ffi::CString;
use std::io::IsTerminal;
use std::os::fd::BorrowedFd;
use std::os::unix::fs::{FileTypeExt, MetadataExt, PermissionsExt};
use std::path::Path;

Expand Down Expand Up @@ -156,17 +158,15 @@ fn eval_unary_path(op: &UnaryOp, s: &str) -> bool {
}

fn eval_terminal(s: &str) -> bool {
let fd = match s.parse::<u32>() {
let fd = match s.parse::<i32>() {
Ok(f) => f,
Err(_) => {
return false;
}
};

// Normally, posixutils would use the atty crate.
// Passing an arbitrary fd requires unsafe isatty in this case.

unsafe { libc::isatty(fd as i32) == 1 }
// Use safe Rust IsTerminal trait with BorrowedFd
unsafe { BorrowedFd::borrow_raw(fd).is_terminal() }
}

fn eval_unary(op_str: &str, s: &str) -> bool {
Expand Down