Change:
For example: i686-gnu, i686-gnu, i686-gnu-nopt, i686-gnu-nopt, i686-gnu, i686-gnu-nopt, i686-gnu, i686-gnu-nopt i686-gnu, i686-gnu, i686-gnu, x8664-gnu-distcheck, i686-gnu-nopt, x8664-gnu-tools, i686-gnu, i686-gnu-nopt, i686-gnu-nopt,
Posted a fix at .

Discussion:
use crate::sys::cvt; use crate::sys::fd; use crate::sys_common::mutex::{StaticMutex, StaticMutexGuard}; <del> use crate::sys_common::rwlock::{RWLockReadGuard, StaticRWLock}; </del> use crate::vec; use libc::{c_char, c_int, c_void};

extern "C" { static mut environ: *const *const c_char; } <del> ptr::addr_of_mut!(environ) </del> <ins> &mut environ </ins> } <del> static ENV_LOCK: StaticRWLock = StaticRWLock::new(); pub fn env_read_lock() -> RWLockReadGuard { ENV_LOCK.read_with_guard() </del> <ins> pub unsafe fn env_lock() -> StaticMutexGuard { // It is UB to attempt to acquire this mutex reentrantly! static ENV_LOCK: StaticMutex = StaticMutex::new(); ENV_LOCK.lock() </ins> } /// Returns a vector of (variable, value) byte-vector pairs for all the /// environment variables of the current process. pub fn env() -> Env { unsafe { <del> let _guard = env_read_lock(); </del> <ins> let _guard = env_lock(); </ins> let mut environ = *environ(); let mut result = Vec::new(); if !environ.is_null() {

// always None as well let k = CString::new(k.as_bytes())?; unsafe { <del> let _guard = env_read_lock(); </del> <ins> let _guard = env_lock(); </ins> let s = libc::getenv(k.as_ptr()) as *const libc::c_char; let ret = if s.is_null() { None

let v = CString::new(v.as_bytes())?; unsafe { <del> let _guard = ENV_LOCK.write_with_guard(); </del> <ins> let _guard = env_lock(); </ins> cvt(libc::setenv(k.as_ptr(), v.as_ptr(), 1)).map(drop) } }

let nbuf = CString::new(n.as_bytes())?; unsafe { <del> let _guard = ENV_LOCK.write_with_guard(); </del> <ins> let _guard = env_lock(); </ins> cvt(libc::unsetenv(nbuf.as_ptr())).map(drop) } }

// a lock any more because the parent won't do anything and the child is // in its own process. let result = unsafe { <del> let _env_lock = sys::os::env_read_lock(); </del> <ins> let _env_lock = sys::os::env_lock(); </ins> cvt(libc::fork())? };

// Similar to when forking, we want to ensure that access to // the environment is synchronized, so make sure to grab the // environment lock before we try to exec. <del> let _lock = sys::os::env_read_lock(); </del> <ins> let _lock = sys::os::env_lock(); </ins> let Err(e) = self.do_exec(theirs, envp.as_ref()); e

cvt_nz(libc::posix_spawnattr_setflags(attrs.0.as_mut_ptr(), flags as _))?; // Make sure we synchronize access to the global `environ` resource <del> let _env_lock = sys::os::env_read_lock(); </del> <ins> let _env_lock = sys::os::env_lock(); </ins> let envp = envp.map(|c| c.as_ptr()).unwrap_or_else(|| *sys::os::environ() as *const _); cvt_nz(libc::posix_spawnp( &mut p.pid,

self.0.destroy() } } <del> // the cfg annotations only exist due to dead code warnings. the code itself is portable #[cfg(unix)] pub struct StaticRWLock(RWLock); #[cfg(unix)] impl StaticRWLock { pub const fn new() -> StaticRWLock { StaticRWLock(RWLock::new()) } /// Acquires shared access to the underlying lock, blocking the current /// thread to do so. /// /// The lock is automatically unlocked when the returned guard is dropped. #[inline] pub fn read_with_guard(&'static self) -> RWLockReadGuard { // SAFETY: All methods require static references, therefore self // cannot be moved between invocations. unsafe { self.0.read(); } RWLockReadGuard(&self.0) } /// Acquires write access to the underlying lock, blocking the current thread /// to do so. /// /// The lock is automatically unlocked when the returned guard is dropped. #[inline] pub fn write_with_guard(&'static self) -> RWLockWriteGuard { // SAFETY: All methods require static references, therefore self // cannot be moved between invocations. unsafe { self.0.write(); } RWLockWriteGuard(&self.0) } } #[cfg(unix)] pub struct RWLockReadGuard(&'static RWLock); #[cfg(unix)] impl Drop for RWLockReadGuard { fn drop(&mut self) { unsafe { self.0.read_unlock() } } } #[cfg(unix)] pub struct RWLockWriteGuard(&'static RWLock); #[cfg(unix)] impl Drop for RWLockWriteGuard { fn drop(&mut self) { unsafe { self.0.write_unlock() } } } </del>