@@ -338,10 +338,43 @@ impl Error for VarError {
338338/// ```
339339#[ stable( feature = "env" , since = "1.0.0" ) ]
340340pub fn set_var < K : AsRef < OsStr > , V : AsRef < OsStr > > ( key : K , value : V ) {
341+ // Safety: This isn't sound. See #27970 for details.
342+ unsafe { _set_var ( key. as_ref ( ) , value. as_ref ( ) ) }
343+ }
344+
345+ /// Sets the environment variable `key` to the value `value` for the currently running
346+ /// process.
347+ ///
348+ /// # Panics
349+ ///
350+ /// This function may panic if `key` is empty, contains an ASCII equals sign `'='`
351+ /// or the NUL character `'\0'`, or when `value` contains the NUL character.
352+ ///
353+ /// # Safety
354+ ///
355+ /// Some platforms only expose non-threadsafe APIs for altering the environment.
356+ /// On these platforms, you must ensure this method is not called when the
357+ /// program is multithreaded and any other thread could be reading or writing
358+ /// the environment.
359+ ///
360+ /// # Examples
361+ ///
362+ /// ```no_run
363+ /// #![feature(unsafe_env)]
364+ /// use std::env;
365+ ///
366+ /// let key = "KEY";
367+ /// unsafe { env::set(key, "VALUE"); } // Make sure you're single-threaded!
368+ /// assert_eq!(env::var(key), Ok("VALUE".to_string()));
369+ /// ```
370+ #[ unstable( feature = "unsafe_env" , issue = "none" ) ]
371+ pub unsafe fn set < K : AsRef < OsStr > , V : AsRef < OsStr > > ( key : K , value : V ) {
341372 _set_var ( key. as_ref ( ) , value. as_ref ( ) )
342373}
343374
344- fn _set_var ( key : & OsStr , value : & OsStr ) {
375+ // Safety: This can only be called when the program is single-threaded or when
376+ // no other thread touches the environment.
377+ unsafe fn _set_var ( key : & OsStr , value : & OsStr ) {
345378 os_imp:: setenv ( key, value) . unwrap_or_else ( |e| {
346379 panic ! ( "failed to set environment variable `{:?}` to `{:?}`: {}" , key, value, e)
347380 } )
@@ -380,10 +413,46 @@ fn _set_var(key: &OsStr, value: &OsStr) {
380413/// ```
381414#[ stable( feature = "env" , since = "1.0.0" ) ]
382415pub fn remove_var < K : AsRef < OsStr > > ( key : K ) {
416+ // Safety: This isn't sound. See #27970 for details.
417+ unsafe { _remove_var ( key. as_ref ( ) ) }
418+ }
419+
420+ /// Removes an environment variable from the environment of the currently running process.
421+ ///
422+ /// # Panics
423+ ///
424+ /// This function may panic if `key` is empty, contains an ASCII equals sign
425+ /// `'='` or the NUL character `'\0'`, or when the value contains the NUL
426+ /// character.
427+ ///
428+ /// # Safety
429+ ///
430+ /// Some platforms only expose non-threadsafe APIs for altering the environment.
431+ /// On these platforms, you must ensure this method is not called when the
432+ /// program is multithreaded and any other thread could be reading or writing
433+ /// the environment.
434+ ///
435+ /// # Examples
436+ ///
437+ /// ```no_run
438+ /// #![feature(unsafe_env)]
439+ /// use std::env;
440+ ///
441+ /// let key = "KEY";
442+ /// unsafe { env::set(key, "VALUE"); } // Make sure you're single-threaded!
443+ /// assert_eq!(env::var(key), Ok("VALUE".to_string()));
444+ ///
445+ /// unsafe { env::unset(key); } // Make sure you're single-threaded!
446+ /// assert!(env::var(key).is_err());
447+ /// ```
448+ #[ unstable( feature = "unsafe_env" , issue = "none" ) ]
449+ pub unsafe fn unset < K : AsRef < OsStr > > ( key : K ) {
383450 _remove_var ( key. as_ref ( ) )
384451}
385452
386- fn _remove_var ( key : & OsStr ) {
453+ // Safety: This can only be called when the program is single-threaded or when
454+ // no other thread touches the environment.
455+ unsafe fn _remove_var ( key : & OsStr ) {
387456 os_imp:: unsetenv ( key)
388457 . unwrap_or_else ( |e| panic ! ( "failed to remove environment variable `{:?}`: {}" , key, e) )
389458}
0 commit comments