diff --git a/codex-rs/core/src/exec.rs b/codex-rs/core/src/exec.rs index f7a145663..0378f5ddf 100644 --- a/codex-rs/core/src/exec.rs +++ b/codex-rs/core/src/exec.rs @@ -781,6 +781,15 @@ mod tests { #[cfg(unix)] #[tokio::test] async fn kill_child_process_group_kills_grandchildren_on_timeout() -> Result<()> { + // On Linux/macOS, /bin/bash is typically present; on FreeBSD/OpenBSD, + // prefer /bin/sh to avoid NotFound errors. + #[cfg(any(target_os = "freebsd", target_os = "openbsd"))] + let command = vec![ + "/bin/sh".to_string(), + "-c".to_string(), + "sleep 60 & echo $!; sleep 60".to_string(), + ]; + #[cfg(all(unix, not(any(target_os = "freebsd", target_os = "openbsd"))))] let command = vec![ "/bin/bash".to_string(), "-c".to_string(), diff --git a/codex-rs/core/src/shell.rs b/codex-rs/core/src/shell.rs index a275b2e39..ac115facb 100644 --- a/codex-rs/core/src/shell.rs +++ b/codex-rs/core/src/shell.rs @@ -358,7 +358,8 @@ mod tests { assert!( shell_path == PathBuf::from("/bin/bash") - || shell_path == PathBuf::from("/usr/bin/bash"), + || shell_path == PathBuf::from("/usr/bin/bash") + || shell_path == PathBuf::from("/usr/local/bin/bash"), "shell path: {shell_path:?}", ); } diff --git a/codex-rs/core/tests/suite/shell_serialization.rs b/codex-rs/core/tests/suite/shell_serialization.rs index 4db284767..9c49e95f5 100644 --- a/codex-rs/core/tests/suite/shell_serialization.rs +++ b/codex-rs/core/tests/suite/shell_serialization.rs @@ -366,7 +366,7 @@ async fn shell_output_for_freeform_tool_records_duration( let test = builder.build(&server).await?; let call_id = "shell-structured"; - let responses = shell_responses(call_id, vec!["/bin/bash", "-c", "sleep 1"], output_type)?; + let responses = shell_responses(call_id, vec!["/bin/sh", "-c", "sleep 1"], output_type)?; let mock = mount_sse_sequence(&server, responses).await; test.submit_turn_with_policy(