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;
|
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(())
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue