From 4b5c3efe85bf3dd735401f40d44eda16dd1c67c2 Mon Sep 17 00:00:00 2001 From: Jeffrey Finkelstein Date: Sat, 22 May 2021 10:50:00 -0400 Subject: [PATCH] realpath: use uucore::fs::canonicalize() Use the `uucore::fs::canonicalize()` function to simplify the implementation of `realpath`. --- src/uu/realpath/src/realpath.rs | 78 ++++++++++----------------------- 1 file changed, 24 insertions(+), 54 deletions(-) diff --git a/src/uu/realpath/src/realpath.rs b/src/uu/realpath/src/realpath.rs index 37ff70fb2..937cee5bd 100644 --- a/src/uu/realpath/src/realpath.rs +++ b/src/uu/realpath/src/realpath.rs @@ -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(()) }