1
Fork 0
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:
Jeffrey Finkelstein 2021-05-22 10:50:00 -04:00
parent bee3b1237c
commit 4b5c3efe85

View file

@ -11,7 +11,6 @@
extern crate uucore; extern crate uucore;
use clap::{App, Arg}; use clap::{App, Arg};
use std::fs;
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
use uucore::fs::{canonicalize, CanonicalizeMode}; 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 quiet = matches.is_present(OPT_QUIET);
let mut retcode = 0; let mut retcode = 0;
for path in &paths { 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 = 1
}; };
} }
retcode retcode
} }
fn resolve_path(p: &Path, strip: bool, zero: bool, quiet: bool) -> bool { /// Resolve a path to an absolute form and print it.
let abs = canonicalize(p, CanonicalizeMode::Normal).unwrap(); ///
/// If `strip` is `true`, then this function does not attempt to resolve
if strip { /// symbolic links in the path. If `zero` is `true`, then this function
if zero { /// prints the path followed by the null byte (`'\0'`) instead of a
print!("{}\0", p.display()); /// newline character (`'\n'`).
} else { ///
println!("{}", p.display()) /// # Errors
} ///
return true; /// 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 mut result = PathBuf::new(); let mode = if strip {
let mut links_left = 256; CanonicalizeMode::None
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());
} else { } else {
println!("{}", result.display()); CanonicalizeMode::Normal
} };
let abs = canonicalize(p, mode)?;
true let line_ending = if zero { '\0' } else { '\n' };
print!("{}{}", abs.display(), line_ending);
Ok(())
} }