Auto merge of #26896 - tbu-:pr_getcwd, r=alexcrichton
(On Windows, it works already.)
This commit is contained in:
commit
fe0b5c0d38
@ -36,7 +36,6 @@ use sys::os as os_imp;
|
||||
///
|
||||
/// * Current directory does not exist.
|
||||
/// * There are insufficient permissions to access the current directory.
|
||||
/// * The internal buffer is not large enough to hold the path.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
|
@ -22,25 +22,17 @@ use io;
|
||||
use iter;
|
||||
use libc::{self, c_int, c_char, c_void};
|
||||
use mem;
|
||||
use ptr;
|
||||
use path::{self, PathBuf};
|
||||
use ptr;
|
||||
use slice;
|
||||
use str;
|
||||
use sys::c;
|
||||
use sys::fd;
|
||||
use vec;
|
||||
|
||||
const BUF_BYTES: usize = 2048;
|
||||
const GETCWD_BUF_BYTES: usize = 2048;
|
||||
const TMPBUF_SZ: usize = 128;
|
||||
|
||||
fn bytes2path(b: &[u8]) -> PathBuf {
|
||||
PathBuf::from(<OsStr as OsStrExt>::from_bytes(b))
|
||||
}
|
||||
|
||||
fn os2path(os: OsString) -> PathBuf {
|
||||
bytes2path(os.as_bytes())
|
||||
}
|
||||
|
||||
/// Returns the platform-specific value of errno
|
||||
pub fn errno() -> i32 {
|
||||
#[cfg(any(target_os = "macos",
|
||||
@ -102,12 +94,24 @@ pub fn error_string(errno: i32) -> String {
|
||||
}
|
||||
|
||||
pub fn getcwd() -> io::Result<PathBuf> {
|
||||
let mut buf = [0 as c_char; BUF_BYTES];
|
||||
unsafe {
|
||||
if libc::getcwd(buf.as_mut_ptr(), buf.len() as libc::size_t).is_null() {
|
||||
Err(io::Error::last_os_error())
|
||||
} else {
|
||||
Ok(bytes2path(CStr::from_ptr(buf.as_ptr()).to_bytes()))
|
||||
let mut buf = Vec::new();
|
||||
let mut n = GETCWD_BUF_BYTES;
|
||||
loop {
|
||||
unsafe {
|
||||
buf.reserve(n);
|
||||
let ptr = buf.as_mut_ptr() as *mut libc::c_char;
|
||||
if !libc::getcwd(ptr, buf.capacity() as libc::size_t).is_null() {
|
||||
let len = CStr::from_ptr(buf.as_ptr() as *const libc::c_char).to_bytes().len();
|
||||
buf.set_len(len);
|
||||
buf.shrink_to_fit();
|
||||
return Ok(PathBuf::from(OsString::from_vec(buf)));
|
||||
} else {
|
||||
let error = io::Error::last_os_error();
|
||||
if error.raw_os_error() != Some(libc::ERANGE) {
|
||||
return Err(error);
|
||||
}
|
||||
}
|
||||
n *= 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -129,11 +133,14 @@ pub struct SplitPaths<'a> {
|
||||
}
|
||||
|
||||
pub fn split_paths<'a>(unparsed: &'a OsStr) -> SplitPaths<'a> {
|
||||
fn bytes_to_path(b: &[u8]) -> PathBuf {
|
||||
PathBuf::from(<OsStr as OsStrExt>::from_bytes(b))
|
||||
}
|
||||
fn is_colon(b: &u8) -> bool { *b == b':' }
|
||||
let unparsed = unparsed.as_bytes();
|
||||
SplitPaths {
|
||||
iter: unparsed.split(is_colon as fn(&u8) -> bool)
|
||||
.map(bytes2path as fn(&'a [u8]) -> PathBuf)
|
||||
.map(bytes_to_path as fn(&'a [u8]) -> PathBuf)
|
||||
}
|
||||
}
|
||||
|
||||
@ -444,7 +451,7 @@ pub fn page_size() -> usize {
|
||||
}
|
||||
|
||||
pub fn temp_dir() -> PathBuf {
|
||||
getenv("TMPDIR".as_ref()).map(os2path).unwrap_or_else(|| {
|
||||
getenv("TMPDIR".as_ref()).map(PathBuf::from).unwrap_or_else(|| {
|
||||
if cfg!(target_os = "android") {
|
||||
PathBuf::from("/data/local/tmp")
|
||||
} else {
|
||||
@ -456,7 +463,7 @@ pub fn temp_dir() -> PathBuf {
|
||||
pub fn home_dir() -> Option<PathBuf> {
|
||||
return getenv("HOME".as_ref()).or_else(|| unsafe {
|
||||
fallback()
|
||||
}).map(os2path);
|
||||
}).map(PathBuf::from);
|
||||
|
||||
#[cfg(any(target_os = "android",
|
||||
target_os = "ios"))]
|
||||
|
Loading…
x
Reference in New Issue
Block a user