//! Build-time bubblewrap entrypoint. //! //! On Linux targets, the build script compiles bubblewrap's C sources and //! exposes a `bwrap_main` symbol that we can call via FFI. #[cfg(vendored_bwrap_available)] mod imp { use std::ffi::CString; use std::fs::File; use std::os::raw::c_char; unsafe extern "C" { fn bwrap_main(argc: libc::c_int, argv: *const *const c_char) -> libc::c_int; } fn argv_to_cstrings(argv: &[String]) -> Vec { let mut cstrings: Vec = Vec::with_capacity(argv.len()); for arg in argv { match CString::new(arg.as_str()) { Ok(value) => cstrings.push(value), Err(err) => panic!("failed to convert argv to CString: {err}"), } } cstrings } /// Run the build-time bubblewrap `main` function and return its exit code. /// /// On success, bubblewrap will `execve` into the target program and this /// function will never return. A return value therefore implies failure. pub(crate) fn run_vendored_bwrap_main( argv: &[String], _preserved_files: &[File], ) -> libc::c_int { let cstrings = argv_to_cstrings(argv); let mut argv_ptrs: Vec<*const c_char> = cstrings.iter().map(|arg| arg.as_ptr()).collect(); argv_ptrs.push(std::ptr::null()); // SAFETY: We provide a null-terminated argv vector whose pointers // remain valid for the duration of the call. unsafe { bwrap_main(cstrings.len() as libc::c_int, argv_ptrs.as_ptr()) } } /// Execute the build-time bubblewrap `main` function with the given argv. pub(crate) fn exec_vendored_bwrap(argv: Vec, preserved_files: Vec) -> ! { let exit_code = run_vendored_bwrap_main(&argv, &preserved_files); std::process::exit(exit_code); } } #[cfg(not(vendored_bwrap_available))] mod imp { use std::fs::File; /// Panics with a clear error when the build-time bwrap path is not enabled. pub(crate) fn run_vendored_bwrap_main( _argv: &[String], _preserved_files: &[File], ) -> libc::c_int { panic!( r#"build-time bubblewrap is not available in this build. codex-linux-sandbox should always compile vendored bubblewrap on Linux targets. Notes: - ensure the target OS is Linux - libcap headers must be available via pkg-config - bubblewrap sources expected at codex-rs/vendor/bubblewrap (default)"# ); } /// Panics with a clear error when the build-time bwrap path is not enabled. pub(crate) fn exec_vendored_bwrap(_argv: Vec, _preserved_files: Vec) -> ! { let _ = run_vendored_bwrap_main(&[], &[]); unreachable!("run_vendored_bwrap_main should always panic in this configuration") } } pub(crate) use imp::exec_vendored_bwrap; pub(crate) use imp::run_vendored_bwrap_main;