@@ -338,10 +338,43 @@ impl Error for VarError {
338
338
/// ```
339
339
#[ stable( feature = "env" , since = "1.0.0" ) ]
340
340
pub 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 ) {
341
372
_set_var ( key. as_ref ( ) , value. as_ref ( ) )
342
373
}
343
374
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 ) {
345
378
os_imp:: setenv ( key, value) . unwrap_or_else ( |e| {
346
379
panic ! ( "failed to set environment variable `{:?}` to `{:?}`: {}" , key, value, e)
347
380
} )
@@ -380,10 +413,46 @@ fn _set_var(key: &OsStr, value: &OsStr) {
380
413
/// ```
381
414
#[ stable( feature = "env" , since = "1.0.0" ) ]
382
415
pub 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 ) {
383
450
_remove_var ( key. as_ref ( ) )
384
451
}
385
452
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 ) {
387
456
os_imp:: unsetenv ( key)
388
457
. unwrap_or_else ( |e| panic ! ( "failed to remove environment variable `{:?}`: {}" , key, e) )
389
458
}
0 commit comments