mirror of
https://github.com/rust-lang/rust.git
synced 2025-04-28 11:07:42 +00:00
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.
This commit is contained in:
commit
5624ac7c47
@ -69,7 +69,7 @@ impl DoubleEndedIterator for Args {
|
|||||||
target_os = "fuchsia"))]
|
target_os = "fuchsia"))]
|
||||||
mod imp {
|
mod imp {
|
||||||
use os::unix::prelude::*;
|
use os::unix::prelude::*;
|
||||||
use mem;
|
use ptr;
|
||||||
use ffi::{CStr, OsString};
|
use ffi::{CStr, OsString};
|
||||||
use marker::PhantomData;
|
use marker::PhantomData;
|
||||||
use libc;
|
use libc;
|
||||||
@ -77,49 +77,42 @@ mod imp {
|
|||||||
|
|
||||||
use sys_common::mutex::Mutex;
|
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();
|
static LOCK: Mutex = Mutex::new();
|
||||||
|
|
||||||
pub unsafe fn init(argc: isize, argv: *const *const u8) {
|
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();
|
LOCK.lock();
|
||||||
let ptr = get_global_ptr();
|
ARGC = argc;
|
||||||
assert!((*ptr).is_none());
|
ARGV = argv;
|
||||||
(*ptr) = Some(box args);
|
|
||||||
LOCK.unlock();
|
LOCK.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub unsafe fn cleanup() {
|
pub unsafe fn cleanup() {
|
||||||
LOCK.lock();
|
LOCK.lock();
|
||||||
*get_global_ptr() = None;
|
ARGC = 0;
|
||||||
|
ARGV = ptr::null();
|
||||||
LOCK.unlock();
|
LOCK.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn args() -> Args {
|
pub fn args() -> Args {
|
||||||
let bytes = clone().unwrap_or(Vec::new());
|
Args {
|
||||||
let v: Vec<OsString> = bytes.into_iter().map(|v| {
|
iter: clone().into_iter(),
|
||||||
OsStringExt::from_vec(v)
|
_dont_send_or_sync_me: PhantomData
|
||||||
}).collect();
|
}
|
||||||
Args { iter: v.into_iter(), _dont_send_or_sync_me: PhantomData }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn clone() -> Option<Vec<Vec<u8>>> {
|
fn clone() -> Vec<OsString> {
|
||||||
unsafe {
|
unsafe {
|
||||||
LOCK.lock();
|
LOCK.lock();
|
||||||
let ptr = get_global_ptr();
|
let ret = (0..ARGC).map(|i| {
|
||||||
let ret = (*ptr).as_ref().map(|s| (**s).clone());
|
let cstr = CStr::from_ptr(*ARGV.offset(i) as *const libc::c_char);
|
||||||
|
OsStringExt::from_vec(cstr.to_bytes().to_vec())
|
||||||
|
}).collect();
|
||||||
LOCK.unlock();
|
LOCK.unlock();
|
||||||
return ret
|
return ret
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_global_ptr() -> *mut Option<Box<Vec<Vec<u8>>>> {
|
|
||||||
unsafe { mem::transmute(&GLOBAL_ARGS_PTR) }
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(any(target_os = "macos",
|
#[cfg(any(target_os = "macos",
|
||||||
|
Loading…
Reference in New Issue
Block a user