提交 5624ac7c 编写于 作者: G Guillaume Gomez 提交者: GitHub

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.
......@@ -69,7 +69,7 @@ fn next_back(&mut self) -> Option<OsString> { self.iter.next_back() }
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",
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册