Skip to content

Commit b945a80

Browse files
Rollup merge of rust-lang#153718 - asomers:environ-freebsd, r=Mark-Simulacrum
Fix environ on FreeBSD with cdylib targets that use -Wl,--no-undefined . Instead of relying on the linker to find the 'environ' symbol, use dlsym. This fixes using `environ` from cdylibs that link with `-Wl,--no-undefined` . Fixes rust-lang#153451 Sponsored by: ConnectWise
2 parents 331d5dc + 44d6cd2 commit b945a80

1 file changed

Lines changed: 18 additions & 1 deletion

File tree

library/std/src/sys/env/unix.rs

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,25 @@ pub unsafe fn environ() -> *mut *const *const c_char {
3838
unsafe { libc::_NSGetEnviron() as *mut *const *const c_char }
3939
}
4040

41+
// On FreeBSD, environ comes from CRT rather than libc
42+
#[cfg(target_os = "freebsd")]
43+
pub unsafe fn environ() -> *mut *const *const c_char {
44+
use crate::sync::LazyLock;
45+
46+
struct Environ(*mut *const *const c_char);
47+
unsafe impl Send for Environ {}
48+
unsafe impl Sync for Environ {}
49+
50+
static ENVIRON: LazyLock<Environ> = LazyLock::new(|| {
51+
Environ(unsafe {
52+
libc::dlsym(libc::RTLD_DEFAULT, c"environ".as_ptr()) as *mut *const *const c_char
53+
})
54+
});
55+
ENVIRON.0
56+
}
57+
4158
// Use the `environ` static which is part of POSIX.
42-
#[cfg(not(target_vendor = "apple"))]
59+
#[cfg(not(any(target_os = "freebsd", target_vendor = "apple")))]
4360
pub unsafe fn environ() -> *mut *const *const c_char {
4461
unsafe extern "C" {
4562
static mut environ: *const *const c_char;

0 commit comments

Comments
 (0)