mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-07-28 03:27:44 +00:00
realpath: use uucore::fs::canonicalize()
Use the `uucore::fs::canonicalize()` function to simplify the implementation of `realpath`.
This commit is contained in:
parent
bee3b1237c
commit
4b5c3efe85
1 changed files with 24 additions and 54 deletions
|
@ -11,7 +11,6 @@
|
|||
extern crate uucore;
|
||||
|
||||
use clap::{App, Arg};
|
||||
use std::fs;
|
||||
use std::path::{Path, PathBuf};
|
||||
use uucore::fs::{canonicalize, CanonicalizeMode};
|
||||
|
||||
|
@ -75,64 +74,35 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
|||
let quiet = matches.is_present(OPT_QUIET);
|
||||
let mut retcode = 0;
|
||||
for path in &paths {
|
||||
if !resolve_path(path, strip, zero, quiet) {
|
||||
if let Err(e) = resolve_path(path, strip, zero) {
|
||||
if !quiet {
|
||||
show_error!("{}: {}", e, path.display());
|
||||
}
|
||||
retcode = 1
|
||||
};
|
||||
}
|
||||
retcode
|
||||
}
|
||||
|
||||
fn resolve_path(p: &Path, strip: bool, zero: bool, quiet: bool) -> bool {
|
||||
let abs = canonicalize(p, CanonicalizeMode::Normal).unwrap();
|
||||
|
||||
if strip {
|
||||
if zero {
|
||||
print!("{}\0", p.display());
|
||||
} else {
|
||||
println!("{}", p.display())
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
let mut result = PathBuf::new();
|
||||
let mut links_left = 256;
|
||||
|
||||
for part in abs.components() {
|
||||
result.push(part.as_os_str());
|
||||
loop {
|
||||
if links_left == 0 {
|
||||
if !quiet {
|
||||
show_error!("Too many symbolic links: {}", p.display())
|
||||
};
|
||||
return false;
|
||||
}
|
||||
match fs::metadata(result.as_path()) {
|
||||
Err(_) => break,
|
||||
Ok(ref m) if !m.file_type().is_symlink() => break,
|
||||
Ok(_) => {
|
||||
links_left -= 1;
|
||||
match fs::read_link(result.as_path()) {
|
||||
Ok(x) => {
|
||||
result.pop();
|
||||
result.push(x.as_path());
|
||||
}
|
||||
_ => {
|
||||
if !quiet {
|
||||
show_error!("Invalid path: {}", p.display())
|
||||
};
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if zero {
|
||||
print!("{}\0", result.display());
|
||||
/// Resolve a path to an absolute form and print it.
|
||||
///
|
||||
/// If `strip` is `true`, then this function does not attempt to resolve
|
||||
/// symbolic links in the path. If `zero` is `true`, then this function
|
||||
/// prints the path followed by the null byte (`'\0'`) instead of a
|
||||
/// newline character (`'\n'`).
|
||||
///
|
||||
/// # Errors
|
||||
///
|
||||
/// This function returns an error if there is a problem resolving
|
||||
/// symbolic links.
|
||||
fn resolve_path(p: &Path, strip: bool, zero: bool) -> std::io::Result<()> {
|
||||
let mode = if strip {
|
||||
CanonicalizeMode::None
|
||||
} else {
|
||||
println!("{}", result.display());
|
||||
}
|
||||
|
||||
true
|
||||
CanonicalizeMode::Normal
|
||||
};
|
||||
let abs = canonicalize(p, mode)?;
|
||||
let line_ending = if zero { '\0' } else { '\n' };
|
||||
print!("{}{}", abs.display(), line_ending);
|
||||
Ok(())
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue