mirror of
https://github.com/uutils/coreutils
synced 2024-11-17 02:08:09 +00:00
uucore::fs: don't canonicalize last component
Change the behavior of `uucore::fs::canonicalize()` when `can_mode` is `CanonicalizeMode::None` so that it does not attempt to resolve the final component if it is a symbolic link. This matches the behavior of the function for the non-final components of a path when `can_mode` is `None`.
This commit is contained in:
parent
66cfdb8644
commit
bee3b1237c
1 changed files with 30 additions and 0 deletions
|
@ -54,11 +54,19 @@ pub fn resolve_relative_path(path: &Path) -> Cow<Path> {
|
|||
result.into()
|
||||
}
|
||||
|
||||
/// Controls how symbolic links should be handled when canonicalizing a path.
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
||||
pub enum CanonicalizeMode {
|
||||
/// Do not resolve any symbolic links.
|
||||
None,
|
||||
|
||||
/// Resolve all symbolic links.
|
||||
Normal,
|
||||
|
||||
/// Resolve symbolic links, ignoring errors on the final component.
|
||||
Existing,
|
||||
|
||||
/// Resolve symbolic links, ignoring errors on the non-final components.
|
||||
Missing,
|
||||
}
|
||||
|
||||
|
@ -125,6 +133,24 @@ fn resolve<P: AsRef<Path>>(original: P) -> IOResult<PathBuf> {
|
|||
Ok(result)
|
||||
}
|
||||
|
||||
/// Return the canonical, absolute form of a path.
|
||||
///
|
||||
/// This function is a generalization of [`std::fs::canonicalize`] that
|
||||
/// allows controlling how symbolic links are resolved and how to deal
|
||||
/// with missing components. It returns the canonical, absolute form of
|
||||
/// a path. The `can_mode` parameter controls how symbolic links are
|
||||
/// resolved:
|
||||
///
|
||||
/// * [`CanonicalizeMode::Normal`] makes this function behave like
|
||||
/// [`std::fs::canonicalize`], resolving symbolic links and returning
|
||||
/// an error if the path does not exist.
|
||||
/// * [`CanonicalizeMode::Missing`] makes this function ignore non-final
|
||||
/// components of the path that could not be resolved.
|
||||
/// * [`CanonicalizeMode::Existing`] makes this function return an error
|
||||
/// if the final component of the path does not exist.
|
||||
/// * [`CanonicalizeMode::None`] makes this function not try to resolve
|
||||
/// any symbolic links.
|
||||
///
|
||||
pub fn canonicalize<P: AsRef<Path>>(original: P, can_mode: CanonicalizeMode) -> IOResult<PathBuf> {
|
||||
// Create an absolute path
|
||||
let original = original.as_ref();
|
||||
|
@ -180,6 +206,10 @@ pub fn canonicalize<P: AsRef<Path>>(original: P, can_mode: CanonicalizeMode) ->
|
|||
|
||||
result.push(parts.last().unwrap());
|
||||
|
||||
if can_mode == CanonicalizeMode::None {
|
||||
return Ok(result);
|
||||
}
|
||||
|
||||
match resolve(&result) {
|
||||
Err(e) => {
|
||||
if can_mode == CanonicalizeMode::Existing {
|
||||
|
|
Loading…
Reference in a new issue