@@ -11,14 +11,12 @@ use crate::path::{self, PathBuf, Path};
1111use crate :: ptr;
1212use crate :: slice;
1313use crate :: str;
14- use crate :: sys_common:: mutex:: Mutex ;
14+ use crate :: sys_common:: mutex:: { Mutex , MutexGuard } ;
1515use crate :: sys:: cvt;
1616/*use sys::fd; this one is probably important */
1717use crate :: vec;
1818
1919const TMPBUF_SZ : usize = 128 ;
20- static ENV_LOCK : Mutex = Mutex :: new ( ) ;
21-
2220
2321// This is a terrible fix
2422use crate :: sys:: os_str:: Buf ;
@@ -200,11 +198,18 @@ pub unsafe fn environ() -> *mut *const *const c_char {
200198 & mut environ
201199}
202200
201+ pub unsafe fn env_lock ( ) -> MutexGuard < ' static > {
202+ // We never call `ENV_LOCK.init()`, so it is UB to attempt to
203+ // acquire this mutex reentrantly!
204+ static ENV_LOCK : Mutex = Mutex :: new ( ) ;
205+ ENV_LOCK . lock ( )
206+ }
207+
203208/// Returns a vector of (variable, value) byte-vector pairs for all the
204209/// environment variables of the current process.
205210pub fn env ( ) -> Env {
206211 unsafe {
207- let _guard = ENV_LOCK . lock ( ) ;
212+ let _guard = env_lock ( ) ;
208213 let mut environ = * environ ( ) ;
209214 if environ == ptr:: null ( ) {
210215 panic ! ( "os::env() failure getting env string from OS: {}" ,
@@ -244,7 +249,7 @@ pub fn getenv(k: &OsStr) -> io::Result<Option<OsString>> {
244249 // always None as well
245250 let k = CString :: new ( k. as_bytes ( ) ) ?;
246251 unsafe {
247- let _guard = ENV_LOCK . lock ( ) ;
252+ let _guard = env_lock ( ) ;
248253 let s = libc:: getenv ( k. as_ptr ( ) ) as * const libc:: c_char ;
249254 let ret = if s. is_null ( ) {
250255 None
@@ -260,7 +265,7 @@ pub fn setenv(k: &OsStr, v: &OsStr) -> io::Result<()> {
260265 let v = CString :: new ( v. as_bytes ( ) ) ?;
261266
262267 unsafe {
263- let _guard = ENV_LOCK . lock ( ) ;
268+ let _guard = env_lock ( ) ;
264269 cvt ( libc:: setenv ( k. as_ptr ( ) , v. as_ptr ( ) , 1 ) ) . map ( |_| ( ) )
265270 }
266271}
@@ -269,7 +274,7 @@ pub fn unsetenv(n: &OsStr) -> io::Result<()> {
269274 let nbuf = CString :: new ( n. as_bytes ( ) ) ?;
270275
271276 unsafe {
272- let _guard = ENV_LOCK . lock ( ) ;
277+ let _guard = env_lock ( ) ;
273278 cvt ( libc:: unsetenv ( nbuf. as_ptr ( ) ) ) . map ( |_| ( ) )
274279 }
275280}
0 commit comments