Auto merge of #26896 - tbu-:pr_getcwd, r=alexcrichton

(On Windows, it works already.)
This commit is contained in:
bors 2015-07-10 16:26:19 +00:00
commit fe0b5c0d38
2 changed files with 26 additions and 20 deletions

View File

@ -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
///

View File

@ -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"))]