diff options
| author | Guillaume Gomez <guillaume1.gomez@gmail.com> | 2018-01-06 02:13:33 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2018-01-06 02:13:33 +0100 |
| commit | 5624ac7c47f508c9975c4bea321d9af6a4bf2ad2 (patch) | |
| tree | b1c9d50c565e97a207c7d3e4945d1ea9e55522e0 /src/libstd | |
| parent | 67e3a2bb2c71c2a59fa5c4bc08e71fe07f25c5c2 (diff) | |
| parent | 91c3eee1735ad72b579f99cbb6919c3471747d94 (diff) | |
| download | rust-5624ac7c47f508c9975c4bea321d9af6a4bf2ad2.tar.gz rust-5624ac7c47f508c9975c4bea321d9af6a4bf2ad2.zip | |
Rollup merge of #47165 - mbrubeck:args, r=alexcrichton
[unix] Don't clone command-line args on startup Fixes part of #47164 and simplifies the `args` code on non-Apple Unix platforms. Note: This could change behavior for programs that use both `std::env::args` *and* unsafe code that mutates `argv` directly. However, these programs already behave differently on different platforms. The new behavior on non-Apple platforms is closer to the existing behavior on Apple platforms.
Diffstat (limited to 'src/libstd')
| -rw-r--r-- | src/libstd/sys/unix/args.rs | 39 |
1 files changed, 16 insertions, 23 deletions
diff --git a/src/libstd/sys/unix/args.rs b/src/libstd/sys/unix/args.rs index 72169773df5..e1c7ffc19e5 100644 --- a/src/libstd/sys/unix/args.rs +++ b/src/libstd/sys/unix/args.rs @@ -69,7 +69,7 @@ impl DoubleEndedIterator for Args { target_os = "fuchsia"))] mod imp { use os::unix::prelude::*; - use mem; + use ptr; use ffi::{CStr, OsString}; use marker::PhantomData; use libc; @@ -77,49 +77,42 @@ mod imp { use sys_common::mutex::Mutex; - static mut GLOBAL_ARGS_PTR: usize = 0; + static mut ARGC: isize = 0; + static mut ARGV: *const *const u8 = ptr::null(); static LOCK: Mutex = Mutex::new(); pub unsafe fn init(argc: isize, argv: *const *const u8) { - let args = (0..argc).map(|i| { - CStr::from_ptr(*argv.offset(i) as *const libc::c_char).to_bytes().to_vec() - }).collect(); - LOCK.lock(); - let ptr = get_global_ptr(); - assert!((*ptr).is_none()); - (*ptr) = Some(box args); + ARGC = argc; + ARGV = argv; LOCK.unlock(); } pub unsafe fn cleanup() { LOCK.lock(); - *get_global_ptr() = None; + ARGC = 0; + ARGV = ptr::null(); LOCK.unlock(); } pub fn args() -> Args { - let bytes = clone().unwrap_or(Vec::new()); - let v: Vec<OsString> = bytes.into_iter().map(|v| { - OsStringExt::from_vec(v) - }).collect(); - Args { iter: v.into_iter(), _dont_send_or_sync_me: PhantomData } + Args { + iter: clone().into_iter(), + _dont_send_or_sync_me: PhantomData + } } - fn clone() -> Option<Vec<Vec<u8>>> { + fn clone() -> Vec<OsString> { unsafe { LOCK.lock(); - let ptr = get_global_ptr(); - let ret = (*ptr).as_ref().map(|s| (**s).clone()); + let ret = (0..ARGC).map(|i| { + let cstr = CStr::from_ptr(*ARGV.offset(i) as *const libc::c_char); + OsStringExt::from_vec(cstr.to_bytes().to_vec()) + }).collect(); LOCK.unlock(); return ret } } - - fn get_global_ptr() -> *mut Option<Box<Vec<Vec<u8>>>> { - unsafe { mem::transmute(&GLOBAL_ARGS_PTR) } - } - } #[cfg(any(target_os = "macos", |
