Make os::getcwd() return IoResult<Path>
os::getcwd() panics if the current directory is not available. According to getcwd(3), there are three cases: - EACCES: Permission denied. - ENOENT: The current working directory has been removed. - ERANGE: The buffer size is less than the actual absolute path. This commit makes os::getcwd() return IoResult<Path>, not just Path, preventing it from panicking. As os::make_absolute() depends on os::getcwd(), it is also modified to return IoResult<Path>. Fixes #16946. [breaking-change]
This commit is contained in:
parent
09e2ad13d0
commit
6f422c4c05
@ -219,7 +219,7 @@ pub fn rust_path() -> Vec<Path> {
|
||||
}
|
||||
None => Vec::new()
|
||||
};
|
||||
let mut cwd = os::getcwd();
|
||||
let mut cwd = os::getcwd().unwrap();
|
||||
// now add in default entries
|
||||
let cwd_dot_rust = cwd.join(".rust");
|
||||
if !env_rust_path.contains(&cwd_dot_rust) {
|
||||
|
@ -134,7 +134,7 @@ impl<'a> PluginLoader<'a> {
|
||||
// Dynamically link a registrar function into the compiler process.
|
||||
fn dylink_registrar(&mut self, vi: &ast::ViewItem, path: Path, symbol: String) {
|
||||
// Make sure the path contains a / or the linker will search for it.
|
||||
let path = os::make_absolute(&path);
|
||||
let path = os::make_absolute(&path).unwrap();
|
||||
|
||||
let lib = match DynamicLibrary::open(Some(&path)) {
|
||||
Ok(lib) => lib,
|
||||
|
@ -231,7 +231,7 @@ pub fn build_session_(sopts: config::Options,
|
||||
if path.is_absolute() {
|
||||
path.clone()
|
||||
} else {
|
||||
os::getcwd().join(&path)
|
||||
os::getcwd().unwrap().join(&path)
|
||||
}
|
||||
);
|
||||
|
||||
@ -246,7 +246,7 @@ pub fn build_session_(sopts: config::Options,
|
||||
plugin_registrar_fn: Cell::new(None),
|
||||
default_sysroot: default_sysroot,
|
||||
local_crate_source_file: local_crate_source_file,
|
||||
working_dir: os::getcwd(),
|
||||
working_dir: os::getcwd().unwrap(),
|
||||
lint_store: RefCell::new(lint::LintStore::new()),
|
||||
lints: RefCell::new(NodeMap::new()),
|
||||
crate_types: RefCell::new(Vec::new()),
|
||||
|
@ -229,7 +229,7 @@ impl<'a> ArchiveBuilder<'a> {
|
||||
pub fn build(self) -> Archive<'a> {
|
||||
// Get an absolute path to the destination, so `ar` will work even
|
||||
// though we run it from `self.work_dir`.
|
||||
let abs_dst = os::getcwd().join(&self.archive.dst);
|
||||
let abs_dst = os::getcwd().unwrap().join(&self.archive.dst);
|
||||
assert!(!abs_dst.is_relative());
|
||||
let mut args = vec![&abs_dst];
|
||||
let mut total_len = abs_dst.as_vec().len();
|
||||
@ -286,7 +286,7 @@ impl<'a> ArchiveBuilder<'a> {
|
||||
// First, extract the contents of the archive to a temporary directory.
|
||||
// We don't unpack directly into `self.work_dir` due to the possibility
|
||||
// of filename collisions.
|
||||
let archive = os::make_absolute(archive);
|
||||
let archive = os::make_absolute(archive).unwrap();
|
||||
run_ar(self.archive.handler, &self.archive.maybe_ar_prog,
|
||||
"x", Some(loc.path()), &[&archive]);
|
||||
|
||||
|
@ -16,7 +16,7 @@ use std::os;
|
||||
/// returned path does not contain any symlinks in its hierarchy.
|
||||
pub fn realpath(original: &Path) -> io::IoResult<Path> {
|
||||
static MAX_LINKS_FOLLOWED: uint = 256;
|
||||
let original = os::make_absolute(original);
|
||||
let original = os::make_absolute(original).unwrap();
|
||||
|
||||
// Right now lstat on windows doesn't work quite well
|
||||
if cfg!(windows) {
|
||||
|
@ -102,9 +102,9 @@ fn get_rpath_relative_to_output(config: &mut RPathConfig,
|
||||
"$ORIGIN"
|
||||
};
|
||||
|
||||
let mut lib = (config.realpath)(&os::make_absolute(lib)).unwrap();
|
||||
let mut lib = (config.realpath)(&os::make_absolute(lib).unwrap()).unwrap();
|
||||
lib.pop();
|
||||
let mut output = (config.realpath)(&os::make_absolute(&config.out_filename)).unwrap();
|
||||
let mut output = (config.realpath)(&os::make_absolute(&config.out_filename).unwrap()).unwrap();
|
||||
output.pop();
|
||||
let relative = lib.path_relative_from(&output);
|
||||
let relative = relative.expect("could not create rpath relative to output");
|
||||
@ -116,7 +116,7 @@ fn get_rpath_relative_to_output(config: &mut RPathConfig,
|
||||
|
||||
fn get_install_prefix_rpath(config: RPathConfig) -> String {
|
||||
let path = (config.get_install_prefix_lib_path)();
|
||||
let path = os::make_absolute(&path);
|
||||
let path = os::make_absolute(&path).unwrap();
|
||||
// FIXME (#9639): This needs to handle non-utf8 paths
|
||||
path.as_str().expect("non-utf8 component in rpath").to_string()
|
||||
}
|
||||
|
@ -974,7 +974,7 @@ mod tests {
|
||||
let prog = pwd_cmd().spawn().unwrap();
|
||||
|
||||
let output = String::from_utf8(prog.wait_with_output().unwrap().output).unwrap();
|
||||
let parent_dir = os::getcwd();
|
||||
let parent_dir = os::getcwd().unwrap();
|
||||
let child_dir = Path::new(output.as_slice().trim());
|
||||
|
||||
let parent_stat = parent_dir.stat().unwrap();
|
||||
@ -989,7 +989,7 @@ mod tests {
|
||||
use os;
|
||||
// test changing to the parent of os::getcwd() because we know
|
||||
// the path exists (and os::getcwd() is not expected to be root)
|
||||
let parent_dir = os::getcwd().dir_path();
|
||||
let parent_dir = os::getcwd().unwrap().dir_path();
|
||||
let prog = pwd_cmd().cwd(&parent_dir).spawn().unwrap();
|
||||
|
||||
let output = String::from_utf8(prog.wait_with_output().unwrap().output).unwrap();
|
||||
|
@ -35,7 +35,8 @@ impl TempDir {
|
||||
/// If no directory can be created, `Err` is returned.
|
||||
pub fn new_in(tmpdir: &Path, suffix: &str) -> IoResult<TempDir> {
|
||||
if !tmpdir.is_absolute() {
|
||||
return TempDir::new_in(&os::make_absolute(tmpdir), suffix);
|
||||
let abs_tmpdir = try!(os::make_absolute(tmpdir));
|
||||
return TempDir::new_in(&abs_tmpdir, suffix);
|
||||
}
|
||||
|
||||
static CNT: atomic::AtomicUint = atomic::INIT_ATOMIC_UINT;
|
||||
|
@ -75,7 +75,7 @@ fn base_port() -> u16 {
|
||||
];
|
||||
|
||||
// FIXME (#9639): This needs to handle non-utf8 paths
|
||||
let path = os::getcwd();
|
||||
let path = os::getcwd().unwrap();
|
||||
let path_s = path.as_str().unwrap();
|
||||
|
||||
let mut final_base = base;
|
||||
|
@ -38,7 +38,7 @@ pub use self::MapError::*;
|
||||
use clone::Clone;
|
||||
use error::{FromError, Error};
|
||||
use fmt;
|
||||
use io::IoResult;
|
||||
use io::{IoResult, IoError};
|
||||
use iter::Iterator;
|
||||
use libc::{c_void, c_int};
|
||||
use libc;
|
||||
@ -76,15 +76,16 @@ pub fn num_cpus() -> uint {
|
||||
pub const TMPBUF_SZ : uint = 1000u;
|
||||
const BUF_BYTES : uint = 2048u;
|
||||
|
||||
/// Returns the current working directory as a Path.
|
||||
/// Returns the current working directory as a `Path`.
|
||||
///
|
||||
/// # Failure
|
||||
/// # Errors
|
||||
///
|
||||
/// Fails if the current working directory value is invalid:
|
||||
/// Returns an `Err` if the current working directory value is invalid.
|
||||
/// Possible cases:
|
||||
///
|
||||
/// * 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.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
@ -92,32 +93,34 @@ const BUF_BYTES : uint = 2048u;
|
||||
/// use std::os;
|
||||
///
|
||||
/// // We assume that we are in a valid directory like "/home".
|
||||
/// let current_working_directory = os::getcwd();
|
||||
/// let current_working_directory = os::getcwd().unwrap();
|
||||
/// println!("The current directory is {}", current_working_directory.display());
|
||||
/// // /home
|
||||
/// ```
|
||||
#[cfg(unix)]
|
||||
pub fn getcwd() -> Path {
|
||||
pub fn getcwd() -> IoResult<Path> {
|
||||
use c_str::CString;
|
||||
|
||||
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() {
|
||||
panic!()
|
||||
Err(IoError::last_error())
|
||||
} else {
|
||||
Ok(Path::new(CString::new(buf.as_ptr(), false)))
|
||||
}
|
||||
Path::new(CString::new(buf.as_ptr(), false))
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the current working directory as a Path.
|
||||
/// Returns the current working directory as a `Path`.
|
||||
///
|
||||
/// # Failure
|
||||
/// # Errors
|
||||
///
|
||||
/// Fails if the current working directory value is invalid.
|
||||
/// Possibles cases:
|
||||
/// Returns an `Err` if the current working directory value is invalid.
|
||||
/// Possible cases:
|
||||
///
|
||||
/// * 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.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
@ -125,23 +128,31 @@ pub fn getcwd() -> Path {
|
||||
/// use std::os;
|
||||
///
|
||||
/// // We assume that we are in a valid directory like "C:\\Windows".
|
||||
/// let current_working_directory = os::getcwd();
|
||||
/// let current_working_directory = os::getcwd().unwrap();
|
||||
/// println!("The current directory is {}", current_working_directory.display());
|
||||
/// // C:\\Windows
|
||||
/// ```
|
||||
#[cfg(windows)]
|
||||
pub fn getcwd() -> Path {
|
||||
pub fn getcwd() -> IoResult<Path> {
|
||||
use libc::DWORD;
|
||||
use libc::GetCurrentDirectoryW;
|
||||
use io::OtherIoError;
|
||||
|
||||
let mut buf = [0 as u16, ..BUF_BYTES];
|
||||
unsafe {
|
||||
if libc::GetCurrentDirectoryW(buf.len() as DWORD, buf.as_mut_ptr()) == 0 as DWORD {
|
||||
panic!();
|
||||
return Err(IoError::last_error());
|
||||
}
|
||||
}
|
||||
Path::new(String::from_utf16(::str::truncate_utf16_at_nul(&buf))
|
||||
.expect("GetCurrentDirectoryW returned invalid UTF-16"))
|
||||
|
||||
match String::from_utf16(::str::truncate_utf16_at_nul(&buf)) {
|
||||
Some(ref cwd) => Ok(Path::new(cwd)),
|
||||
None => Err(IoError {
|
||||
kind: OtherIoError,
|
||||
desc: "GetCurrentDirectoryW returned invalid UTF-16",
|
||||
detail: None,
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
@ -829,20 +840,21 @@ pub fn tmpdir() -> Path {
|
||||
///
|
||||
/// // Assume we're in a path like /home/someuser
|
||||
/// let rel_path = Path::new("..");
|
||||
/// let abs_path = os::make_absolute(&rel_path);
|
||||
/// let abs_path = os::make_absolute(&rel_path).unwrap();
|
||||
/// println!("The absolute path is {}", abs_path.display());
|
||||
/// // Prints "The absolute path is /home"
|
||||
/// ```
|
||||
// NB: this is here rather than in path because it is a form of environment
|
||||
// querying; what it does depends on the process working directory, not just
|
||||
// the input paths.
|
||||
pub fn make_absolute(p: &Path) -> Path {
|
||||
pub fn make_absolute(p: &Path) -> IoResult<Path> {
|
||||
if p.is_absolute() {
|
||||
p.clone()
|
||||
Ok(p.clone())
|
||||
} else {
|
||||
let mut ret = getcwd();
|
||||
ret.push(p);
|
||||
ret
|
||||
getcwd().map(|mut cwd| {
|
||||
cwd.push(p);
|
||||
cwd
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@ -1881,11 +1893,11 @@ mod tests {
|
||||
fn test() {
|
||||
assert!((!Path::new("test-path").is_absolute()));
|
||||
|
||||
let cwd = getcwd();
|
||||
let cwd = getcwd().unwrap();
|
||||
debug!("Current working directory: {}", cwd.display());
|
||||
|
||||
debug!("{}", make_absolute(&Path::new("test-path")).display());
|
||||
debug!("{}", make_absolute(&Path::new("/usr/bin")).display());
|
||||
debug!("{}", make_absolute(&Path::new("test-path")).unwrap().display());
|
||||
debug!("{}", make_absolute(&Path::new("/usr/bin")).unwrap().display());
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -26,7 +26,7 @@ use std::path::Path;
|
||||
|
||||
fn main() {
|
||||
let my_args = os::args();
|
||||
let my_cwd = os::getcwd();
|
||||
let my_cwd = os::getcwd().unwrap();
|
||||
let my_env = os::env();
|
||||
let my_path = Path::new(os::self_exe_name().unwrap());
|
||||
let my_dir = my_path.dir_path();
|
||||
|
@ -123,7 +123,7 @@ fn test_rm_tempdir_close() {
|
||||
// to depend on std
|
||||
fn recursive_mkdir_rel() {
|
||||
let path = Path::new("frob");
|
||||
let cwd = os::getcwd();
|
||||
let cwd = os::getcwd().unwrap();
|
||||
println!("recursive_mkdir_rel: Making: {} in cwd {} [{}]", path.display(),
|
||||
cwd.display(), path.exists());
|
||||
fs::mkdir_recursive(&path, io::USER_RWX);
|
||||
@ -141,7 +141,7 @@ fn recursive_mkdir_dot() {
|
||||
|
||||
fn recursive_mkdir_rel_2() {
|
||||
let path = Path::new("./frob/baz");
|
||||
let cwd = os::getcwd();
|
||||
let cwd = os::getcwd().unwrap();
|
||||
println!("recursive_mkdir_rel_2: Making: {} in cwd {} [{}]", path.display(),
|
||||
cwd.display(), path.exists());
|
||||
fs::mkdir_recursive(&path, io::USER_RWX);
|
||||
|
Loading…
x
Reference in New Issue
Block a user