@@ -576,12 +576,36 @@ impl Iterator for Env {
576
576
}
577
577
}
578
578
579
- #[ cfg( target_os = "macos" ) ]
579
+ // Use `_NSGetEnviron` on Apple platforms.
580
+ //
581
+ // `_NSGetEnviron` is the documented alternative (see `man environ`), and has
582
+ // been available since the first versions of both macOS and iOS.
583
+ //
584
+ // Nowadays, specifically since macOS 10.8, `environ` has been exposed through
585
+ // `libdyld.dylib`, which is linked via. `libSystem.dylib`:
586
+ // <https://github.com/apple-oss-distributions/dyld/blob/dyld-1160.6/libdyld/libdyldGlue.cpp#L913>
587
+ //
588
+ // So in the end, it likely doesn't really matter which option we use, but the
589
+ // performance cost of using `_NSGetEnviron` is extremely miniscule, and it
590
+ // might be ever so slightly more supported, so let's just use that.
591
+ //
592
+ // NOTE: The header where this is defined (`crt_externs.h`) was added to the
593
+ // iOS 13.0 SDK, which has been the source of a great deal of confusion in the
594
+ // past about the availability of this API.
595
+ //
596
+ // NOTE(madsmtm): Neither this nor using `environ` has been verified to not
597
+ // cause App Store rejections; if this is found to be the case, an alternative
598
+ // implementation of this is possible using `[NSProcessInfo environment]`
599
+ // - which internally uses `_NSGetEnviron` and a system-wide lock on the
600
+ // environment variables to protect against `setenv`, so using that might be
601
+ // desirable anyhow? Though it also means that we have to link to Foundation.
602
+ #[ cfg( target_vendor = "apple" ) ]
580
603
pub unsafe fn environ ( ) -> * mut * const * const c_char {
581
604
libc:: _NSGetEnviron ( ) as * mut * const * const c_char
582
605
}
583
606
584
- #[ cfg( not( target_os = "macos" ) ) ]
607
+ // Use the `environ` static which is part of POSIX.
608
+ #[ cfg( not( target_vendor = "apple" ) ) ]
585
609
pub unsafe fn environ ( ) -> * mut * const * const c_char {
586
610
extern "C" {
587
611
static mut environ: * const * const c_char ;
0 commit comments