mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-07-27 11:07:44 +00:00
uucore::fs: add fn resolve_relative_path
This commit is contained in:
parent
136ca4e197
commit
89ac03d1c2
1 changed files with 51 additions and 23 deletions
|
@ -1,18 +1,39 @@
|
|||
/*
|
||||
* This file is part of the uutils coreutils package.
|
||||
*
|
||||
* (c) Joseph Crail <jbcrail@gmail.com>
|
||||
*
|
||||
* 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 <jbcrail@gmail.com>
|
||||
// (c) Jian Zeng <anonymousknight96 AT gmail.com>
|
||||
//
|
||||
// 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<P: AsRef<Path>>(original: P) -> Result<PathBuf> {
|
||||
fn resolve<P: AsRef<Path>>(original: P) -> IOResult<PathBuf> {
|
||||
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<P: AsRef<Path>>(original: P) -> Result<PathBuf> {
|
|||
Ok(path) => {
|
||||
result.pop();
|
||||
result.push(path);
|
||||
},
|
||||
}
|
||||
Err(e) => {
|
||||
return Err(e);
|
||||
}
|
||||
|
@ -51,7 +72,7 @@ fn resolve<P: AsRef<Path>>(original: P) -> Result<PathBuf> {
|
|||
Ok(result)
|
||||
}
|
||||
|
||||
pub fn canonicalize<P: AsRef<Path>>(original: P, can_mode: CanonicalizeMode) -> Result<PathBuf> {
|
||||
pub fn canonicalize<P: AsRef<Path>>(original: P, can_mode: CanonicalizeMode) -> IOResult<PathBuf> {
|
||||
// Create an absolute path
|
||||
let original = original.as_ref();
|
||||
let original = if original.is_absolute() {
|
||||
|
@ -61,20 +82,21 @@ pub fn canonicalize<P: AsRef<Path>>(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<P: AsRef<Path>>(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<P: AsRef<Path>>(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<P: AsRef<Path>>(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);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue