about summary refs log tree commit diff
path: root/src/libstd
diff options
context:
space:
mode:
authorTobias Bucher <tobiasbucher5991@gmail.com>2015-07-09 15:03:10 +0200
committerTobias Bucher <tobiasbucher5991@gmail.com>2015-07-09 15:03:10 +0200
commitd99d4fbf70acce44c14448a572f7dce4cb883ce8 (patch)
tree5b1b6ca0f73742932a069c8147a9adc50130bea0 /src/libstd
parentc8a5b1368e78979eda0420a95381fe6f61f1a086 (diff)
downloadrust-d99d4fbf70acce44c14448a572f7dce4cb883ce8.tar.gz
rust-d99d4fbf70acce44c14448a572f7dce4cb883ce8.zip
Address some comments on the pull request
Diffstat (limited to 'src/libstd')
-rw-r--r--src/libstd/sys/unix/mod.rs37
-rw-r--r--src/libstd/sys/unix/os.rs28
2 files changed, 25 insertions, 40 deletions
diff --git a/src/libstd/sys/unix/mod.rs b/src/libstd/sys/unix/mod.rs
index 90b7d5f4719..5bf8c1e06a6 100644
--- a/src/libstd/sys/unix/mod.rs
+++ b/src/libstd/sys/unix/mod.rs
@@ -79,33 +79,20 @@ pub fn decode_error_kind(errno: i32) -> ErrorKind {
 // without specifying its size. They will only report back whether the buffer
 // was large enough or not.
 //
-// The callback is yielded a (pointer, len) pair which can be
-// passed to a syscall. The `ptr` is valid for `len` items (i8 in this case).
-// The closure is expected to return `None` if the space was insufficient and
-// `Some(r)` if the syscall did not fail due to insufficient space.
+// The callback is yielded an uninitialized vector which can be passed to a
+// syscall. The closure is expected to return `Err(v)` with the passed vector
+// if the space was insufficient and `Ok(r)` if the syscall did not fail due to
+// insufficient space.
 fn fill_bytes_buf<F, T>(mut f: F) -> io::Result<T>
-    where F: FnMut(*mut i8, libc::size_t) -> Option<io::Result<T>>,
+    where F: FnMut(Vec<u8>) -> Result<io::Result<T>,Vec<u8>>,
 {
-    // Start off with a stack buf but then spill over to the heap if we end up
-    // needing more space.
-    let mut stack_buf = [0i8; os::BUF_BYTES];
-    let mut heap_buf = Vec::new();
-    unsafe {
-        let mut n = stack_buf.len();
-        loop {
-            let buf = if n <= stack_buf.len() {
-                &mut stack_buf[..]
-            } else {
-                heap_buf.set_len(0);
-                heap_buf.reserve(n);
-                heap_buf.set_len(n);
-                &mut heap_buf[..]
-            };
-
-            match f(buf.as_mut_ptr(), n as libc::size_t) {
-                None => n *= 2,
-                Some(r) => return r,
-            }
+    let mut buf = Vec::new();
+    let mut n = os::BUF_BYTES;
+    loop {
+        buf.reserve(n);
+        match f(buf) {
+            Err(b) => { buf = b; n *= 2; }
+            Ok(r) => return r,
         }
     }
 }
diff --git a/src/libstd/sys/unix/os.rs b/src/libstd/sys/unix/os.rs
index 6cf07ea077d..ac38d294a6f 100644
--- a/src/libstd/sys/unix/os.rs
+++ b/src/libstd/sys/unix/os.rs
@@ -33,14 +33,6 @@ use vec;
 pub const 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,14 +94,17 @@ pub fn error_string(errno: i32) -> String {
 }
 
 pub fn getcwd() -> io::Result<PathBuf> {
-    super::fill_bytes_buf(|buf, len| {
+    super::fill_bytes_buf(|mut buf| {
         unsafe {
-            Some(if !libc::getcwd(buf, len).is_null() {
-                Ok(bytes2path(CStr::from_ptr(buf).to_bytes()))
+            let ptr = buf.as_mut_ptr() as *mut libc::c_char;
+            Ok(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);
+                Ok(PathBuf::from(OsString::from_bytes(buf).unwrap()))
             } else {
                 let error = io::Error::last_os_error();
                 if error.raw_os_error().unwrap() == libc::ERANGE {
-                    return None;
+                    return Err(buf);
                 }
                 Err(error)
             })
@@ -134,11 +129,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)
     }
 }
 
@@ -449,7 +447,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 {
@@ -461,7 +459,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"))]