From b854a3161a40341bbfa913bb88e3f2df665c95b9 Mon Sep 17 00:00:00 2001 From: Joseph Crail Date: Wed, 6 May 2015 00:14:13 -0400 Subject: [PATCH] Fix realpath and relpath. I used the new Path/PathBuf/PathExt libraries. --- src/realpath/realpath.rs | 39 +++++++++++++++++++-------------------- src/relpath/relpath.rs | 36 ++++++++++++++++++++---------------- 2 files changed, 39 insertions(+), 36 deletions(-) diff --git a/src/realpath/realpath.rs b/src/realpath/realpath.rs index daf749f24..2d3eedecf 100644 --- a/src/realpath/realpath.rs +++ b/src/realpath/realpath.rs @@ -1,5 +1,5 @@ #![crate_name= "realpath"] -#![feature(collections, core, old_io, os, old_path, rustc_private)] +#![feature(file_type, path_ext, rustc_private)] /* * This file is part of the uutils coreutils package. @@ -13,7 +13,10 @@ extern crate getopts; extern crate libc; -use getopts::{optflag, getopts, usage}; +use getopts::{getopts, optflag, usage}; +use std::fs::PathExt; +use std::io::Write; +use std::path::{Path, PathBuf}; #[path = "../common/util.rs"] #[macro_use] mod util; @@ -30,21 +33,21 @@ pub fn uumain(args: Vec) -> i32 { optflag("q", "quiet", "Do not print warnings for invalid paths"), ]; - let opts = match getopts(args.tail(), &options) { + let opts = match getopts(&args[1..], &options) { Ok(m) => m, Err(f) => { show_error!("{}", f); - show_usage(program.as_slice(), &options); + show_usage(program, &options); return 1 } }; if opts.opt_present("V") { version(); return 0 } - if opts.opt_present("h") { show_usage(program.as_slice(), &options); return 0 } + if opts.opt_present("h") { show_usage(program, &options); return 0 } if opts.free.len() == 0 { show_error!("Missing operand: FILENAME, at least one is required"); - println!("Try `{} --help` for more information.", program.as_slice()); + println!("Try `{} --help` for more information.", program); return 1 } @@ -53,7 +56,7 @@ pub fn uumain(args: Vec) -> i32 { let quiet = opts.opt_present("q"); let mut retcode = 0; for path in opts.free.iter() { - if !resolve_path(path.as_slice(), strip, zero, quiet) { + if !resolve_path(path, strip, zero, quiet) { retcode = 1 }; } @@ -61,8 +64,8 @@ pub fn uumain(args: Vec) -> i32 { } fn resolve_path(path: &str, strip: bool, zero: bool, quiet: bool) -> bool { - let p = Path::new(path); - let abs = std::os::make_absolute(&p).unwrap(); + let p = Path::new(path).to_path_buf(); + let abs = p.canonicalize().unwrap(); if strip { if zero { @@ -73,29 +76,25 @@ fn resolve_path(path: &str, strip: bool, zero: bool, quiet: bool) -> bool { return true } - let mut result = match abs.root_path() { - None => crash!(2, "Broken path parse! Report to developers: {}", path), - Some(x) => x, - }; - - let mut links_left = 256isize; + let mut result = PathBuf::new(); + let mut links_left = 256; for part in abs.components() { - result.push(part); + result.push(part.as_ref()); loop { if links_left == 0 { if !quiet { show_error!("Too many symbolic links: {}", path) }; return false } - match std::old_io::fs::lstat(&result) { + match result.as_path().metadata() { Err(_) => break, - Ok(ref s) if s.kind != std::old_io::FileType::Symlink => break, + Ok(ref m) if !m.file_type().is_symlink() => break, Ok(_) => { links_left -= 1; - match std::old_io::fs::readlink(&result) { + match result.as_path().read_link() { Ok(x) => { result.pop(); - result.push(x); + result.push(x.as_path()); }, _ => { if !quiet { diff --git a/src/relpath/relpath.rs b/src/relpath/relpath.rs index d146a36bb..8d3950388 100644 --- a/src/relpath/relpath.rs +++ b/src/relpath/relpath.rs @@ -1,5 +1,5 @@ #![crate_name = "relpath"] -#![feature(collections, core, os, old_path, rustc_private)] +#![feature(path_ext, rustc_private)] /* * This file is part of the uutils coreutils package. @@ -13,7 +13,11 @@ extern crate getopts; extern crate libc; -use getopts::{optflag, optopt, getopts, usage}; +use getopts::{getopts, optflag, optopt, usage}; +use std::env; +use std::fs::PathExt; +use std::io::Write; +use std::path::{Path, PathBuf}; #[path = "../common/util.rs"] #[macro_use] mod util; @@ -28,37 +32,37 @@ pub fn uumain(args: Vec) -> i32 { optopt("d", "", "If any of FROM and TO is not subpath of DIR, output absolute path instead of relative", "DIR"), ]; - let opts = match getopts(args.tail(), &options) { + let opts = match getopts(&args[1..], &options) { Ok(m) => m, Err(f) => { show_error!("{}", f); - show_usage(program.as_slice(), &options); + show_usage(program, &options); return 1 } }; if opts.opt_present("V") { version(); return 0 } - if opts.opt_present("h") { show_usage(program.as_slice(), &options); return 0 } + if opts.opt_present("h") { show_usage(program, &options); return 0 } if opts.free.len() == 0 { show_error!("Missing operand: TO"); - println!("Try `{} --help` for more information.", program.as_slice()); + println!("Try `{} --help` for more information.", program); return 1 } - let to = Path::new(opts.free[0].as_slice()); + let to = Path::new(&opts.free[0]); let from = if opts.free.len() > 1 { - Path::new(opts.free[1].as_slice()) + Path::new(&opts.free[1]).to_path_buf() } else { - std::os::getcwd().unwrap() + env::current_dir().unwrap() }; - let absto = std::os::make_absolute(&to).unwrap(); - let absfrom = std::os::make_absolute(&from).unwrap(); + let absto = to.canonicalize().unwrap(); + let absfrom = from.canonicalize().unwrap(); if opts.opt_present("d") { - let base = Path::new(opts.opt_str("d").unwrap()); - let absbase = std::os::make_absolute(&base).unwrap(); - if !absbase.is_ancestor_of(&absto) || !absbase.is_ancestor_of(&absfrom) { + let base = Path::new(&opts.opt_str("d").unwrap()).to_path_buf(); + let absbase = base.canonicalize().unwrap(); + if !absto.as_path().starts_with(absbase.as_path()) || !absfrom.as_path().starts_with(absbase.as_path()) { println!("{}", absto.display()); return 0 } @@ -73,9 +77,9 @@ pub fn uumain(args: Vec) -> i32 { } } - let mut result = Path::new(""); + let mut result = PathBuf::new(); absfrom.components().skip(suffix_pos).map(|_| result.push("..")).last(); - absto.components().skip(suffix_pos).map(|x| result.push(x)).last(); + absto.components().skip(suffix_pos).map(|x| result.push(x.as_ref())).last(); println!("{}", result.display()); 0