mirror of
https://github.com/rust-lang/rust.git
synced 2025-04-14 21:16:50 +00:00
Make std::env::current_dir
work for path names longer than 2048 bytes on non-Windows
This commit is contained in:
parent
50df2a09b8
commit
c8a5b1368e
@ -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
|
||||
///
|
||||
|
@ -75,6 +75,41 @@ pub fn decode_error_kind(errno: i32) -> ErrorKind {
|
||||
}
|
||||
}
|
||||
|
||||
// Some system functions expect the user to pass a appropiately-sized buffer
|
||||
// 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.
|
||||
fn fill_bytes_buf<F, T>(mut f: F) -> io::Result<T>
|
||||
where F: FnMut(*mut i8, libc::size_t) -> Option<io::Result<T>>,
|
||||
{
|
||||
// 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,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn cvt<T: One + PartialEq + Neg<Output=T>>(t: T) -> io::Result<T> {
|
||||
let one: T = T::one();
|
||||
if t == -one {
|
||||
|
@ -22,15 +22,15 @@ 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;
|
||||
pub const BUF_BYTES: usize = 2048;
|
||||
const TMPBUF_SZ: usize = 128;
|
||||
|
||||
fn bytes2path(b: &[u8]) -> PathBuf {
|
||||
@ -102,14 +102,19 @@ 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()))
|
||||
super::fill_bytes_buf(|buf, len| {
|
||||
unsafe {
|
||||
Some(if !libc::getcwd(buf, len).is_null() {
|
||||
Ok(bytes2path(CStr::from_ptr(buf).to_bytes()))
|
||||
} else {
|
||||
let error = io::Error::last_os_error();
|
||||
if error.raw_os_error().unwrap() == libc::ERANGE {
|
||||
return None;
|
||||
}
|
||||
Err(error)
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
pub fn chdir(p: &path::Path) -> io::Result<()> {
|
||||
|
Loading…
Reference in New Issue
Block a user