diff --git a/src/uucore/fs.rs b/src/uucore/fs.rs index e4929c215..e2a34d814 100644 --- a/src/uucore/fs.rs +++ b/src/uucore/fs.rs @@ -1,18 +1,39 @@ -/* - * This file is part of the uutils coreutils package. - * - * (c) Joseph Crail - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ +// This file is part of the uutils coreutils package. +// +// (c) Joseph Crail +// (c) Jian Zeng +// +// For the full copyright and license information, please view the LICENSE +// file that was distributed with this source code. +// #[cfg(unix)] use super::libc; use std::env; use std::fs; -use std::io::{Error, ErrorKind, Result}; +use std::io::{Error, ErrorKind}; +use std::io::Result as IOResult; use std::path::{Component, Path, PathBuf}; +use std::borrow::Cow; + +#[cfg(unix)] +pub fn resolve_relative_path<'a>(path: &'a Path) -> Cow<'a, Path> { + if path.is_absolute() { + return path.into(); + } + let mut result = env::current_dir().unwrap_or(PathBuf::from("/")); + for comp in path.components() { + match comp { + Component::ParentDir => { + result.pop(); + } + Component::CurDir => (), + Component::Normal(s) => result.push(s), + _ => unreachable!(), + } + } + result.into() +} #[derive(Clone, Copy, Debug, Eq, PartialEq)] pub enum CanonicalizeMode { @@ -22,7 +43,7 @@ pub enum CanonicalizeMode { Missing, } -fn resolve>(original: P) -> Result { +fn resolve>(original: P) -> IOResult { const MAX_LINKS_FOLLOWED: u32 = 255; let mut followed = 0; let mut result = original.as_ref().to_path_buf(); @@ -40,7 +61,7 @@ fn resolve>(original: P) -> Result { Ok(path) => { result.pop(); result.push(path); - }, + } Err(e) => { return Err(e); } @@ -51,7 +72,7 @@ fn resolve>(original: P) -> Result { Ok(result) } -pub fn canonicalize>(original: P, can_mode: CanonicalizeMode) -> Result { +pub fn canonicalize>(original: P, can_mode: CanonicalizeMode) -> IOResult { // Create an absolute path let original = original.as_ref(); let original = if original.is_absolute() { @@ -61,20 +82,21 @@ pub fn canonicalize>(original: P, can_mode: CanonicalizeMode) -> }; let mut result = PathBuf::new(); - let mut parts = vec!(); + let mut parts = vec![]; // Split path by directory separator; add prefix (Windows-only) and root // directory to final path buffer; add remaining parts to temporary // vector for canonicalization. for part in original.components() { match part { - Component::Prefix(_) | Component::RootDir => { + Component::Prefix(_) | + Component::RootDir => { result.push(part.as_os_str()); - }, - Component::CurDir => {}, + } + Component::CurDir => (), Component::ParentDir => { parts.pop(); - }, + } Component::Normal(_) => { parts.push(part.as_os_str()); } @@ -83,7 +105,7 @@ pub fn canonicalize>(original: P, can_mode: CanonicalizeMode) -> // Resolve the symlinks where possible if !parts.is_empty() { - for part in parts[..parts.len()-1].iter() { + for part in parts[..parts.len() - 1].iter() { result.push(part); if can_mode == CanonicalizeMode::None { @@ -91,10 +113,12 @@ pub fn canonicalize>(original: P, can_mode: CanonicalizeMode) -> } match resolve(&result) { - Err(e) => match can_mode { - CanonicalizeMode::Missing => continue, - _ => return Err(e) - }, + Err(e) => { + match can_mode { + CanonicalizeMode::Missing => continue, + _ => return Err(e), + } + } Ok(path) => { result.pop(); result.push(path); @@ -105,7 +129,11 @@ pub fn canonicalize>(original: P, can_mode: CanonicalizeMode) -> result.push(parts.last().unwrap()); match resolve(&result) { - Err(e) => { if can_mode == CanonicalizeMode::Existing { return Err(e); } }, + Err(e) => { + if can_mode == CanonicalizeMode::Existing { + return Err(e); + } + } Ok(path) => { result.pop(); result.push(path);