diff options
| author | bors <bors@rust-lang.org> | 2015-07-10 16:26:19 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2015-07-10 16:26:19 +0000 |
| commit | fe0b5c0d38fc937ff6cf3623c4277b0463b17748 (patch) | |
| tree | 993442ceb596be68d8c7afd7103de54e17c12aa7 /src/libstd/sys | |
| parent | fddfd089b75379f1d25f81541572d69a93f95c4f (diff) | |
| parent | b83ec47808c219cb8e85eeebb370be6466b2d690 (diff) | |
| download | rust-fe0b5c0d38fc937ff6cf3623c4277b0463b17748.tar.gz rust-fe0b5c0d38fc937ff6cf3623c4277b0463b17748.zip | |
Auto merge of #26896 - tbu-:pr_getcwd, r=alexcrichton
(On Windows, it works already.)
Diffstat (limited to 'src/libstd/sys')
| -rw-r--r-- | src/libstd/sys/unix/os.rs | 45 |
1 files changed, 26 insertions, 19 deletions
diff --git a/src/libstd/sys/unix/os.rs b/src/libstd/sys/unix/os.rs index 334dd6b5f18..2b6b50a1a56 100644 --- a/src/libstd/sys/unix/os.rs +++ b/src/libstd/sys/unix/os.rs @@ -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"))] |
