diff options
author | Otavio Salvador <otavio@ossystems.com.br> | 2019-09-21 18:56:00 -0300 |
---|---|---|
committer | Otavio Salvador <otavio@ossystems.com.br> | 2019-09-21 18:56:00 -0300 |
commit | 035c69f9957778a9002679d800ec6dff8a778996 (patch) | |
tree | 89d3d93e3dc749a02cec2c0f5a5d57793794b076 | |
parent | ac5de6b1a91f09851f3b2b46fd5b85a63167247e (diff) | |
download | nix-035c69f9957778a9002679d800ec6dff8a778996.zip |
unistd: getcwd: Double the buffer when need, up to PATH_MAX as limit
We now have a `reserve_double_buffer_size` method which reserves the
double of buffer, up to a limit, allowing it to be reused on other
methods in future.
Signed-off-by: Otavio Salvador <otavio@ossystems.com.br>
-rw-r--r-- | src/unistd.rs | 24 |
1 files changed, 18 insertions, 6 deletions
diff --git a/src/unistd.rs b/src/unistd.rs index 4dca01b9..ea22f38e 100644 --- a/src/unistd.rs +++ b/src/unistd.rs @@ -5,7 +5,7 @@ use {Error, Result, NixPath}; use fcntl::{AtFlags, at_rawfd, fcntl, FdFlag, OFlag}; use fcntl::FcntlArg::F_SETFD; use libc::{self, c_char, c_void, c_int, c_long, c_uint, size_t, pid_t, off_t, - uid_t, gid_t, mode_t}; + uid_t, gid_t, mode_t, PATH_MAX}; use std::{fmt, mem, ptr}; use std::ffi::{CString, CStr, OsString, OsStr}; use std::os::unix::ffi::{OsStringExt, OsStrExt}; @@ -534,6 +534,21 @@ pub fn symlinkat<P1: ?Sized + NixPath, P2: ?Sized + NixPath>( Errno::result(res).map(drop) } +// Double the buffer capacity up to limit. In case it already has +// reached the limit, return Errno::ERANGE. +fn reserve_double_buffer_size<T>(buf: &mut Vec<T>, limit: usize) -> Result<()> { + use std::cmp::min; + + if buf.len() >= limit { + return Err(Error::Sys(Errno::ERANGE)) + } + + let capacity = min(buf.capacity() * 2, limit); + buf.reserve(capacity); + + Ok(()) +} + /// Returns the current directory as a `PathBuf` /// /// Err is returned if the current user doesn't have the permission to read or search a component @@ -576,11 +591,8 @@ pub fn getcwd() -> Result<PathBuf> { } } - // Trigger the internal buffer resizing logic of `Vec` by requiring - // more space than the current capacity. - let cap = buf.capacity(); - buf.set_len(cap); - buf.reserve(1); + // Trigger the internal buffer resizing logic. + reserve_double_buffer_size(&mut buf, PATH_MAX as usize)?; } } } |