1
Fork 0
mirror of https://github.com/RGBCube/uutils-coreutils synced 2025-07-29 12:07:46 +00:00

Merge pull request #670 from jbcrail/stablilize-2

Replace more unstable methods.
This commit is contained in:
Heather 2015-08-01 02:12:45 +03:00
commit 7c69b3a1fd
9 changed files with 155 additions and 137 deletions

1
deps/Cargo.toml vendored
View file

@ -10,6 +10,7 @@ libc = "0.1.8"
getopts = "0.2.11"
bit-vec = "0.4.0"
bit-set = "0.2.0"
vec_map = "0.3.0"
num_cpus = "*"
rand = "0.3.8"
regex = "0.1.38"

View file

@ -12,15 +12,16 @@
// be backported to stable (<= 1.1). This will likely be dropped
// when the path trait stabilizes.
use std::env;
use std::fs;
use std::io;
use std::path::Path;
use std::io::{Error, ErrorKind, Result};
use std::path::{Component, Path, PathBuf};
pub trait UUPathExt {
fn uu_exists(&self) -> bool;
fn uu_is_file(&self) -> bool;
fn uu_is_dir(&self) -> bool;
fn uu_metadata(&self) -> io::Result<fs::Metadata>;
fn uu_metadata(&self) -> Result<fs::Metadata>;
}
impl UUPathExt for Path {
@ -36,7 +37,111 @@ impl UUPathExt for Path {
fs::metadata(self).map(|m| m.is_dir()).unwrap_or(false)
}
fn uu_metadata(&self) -> io::Result<fs::Metadata> {
fn uu_metadata(&self) -> Result<fs::Metadata> {
fs::metadata(self)
}
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
#[allow(dead_code)]
pub enum CanonicalizeMode {
None,
Normal,
Existing,
Missing,
}
#[allow(dead_code)]
fn resolve<P: AsRef<Path>>(original: P) -> Result<PathBuf> {
const MAX_LINKS_FOLLOWED: u32 = 255;
let mut followed = 0;
let mut result = original.as_ref().to_path_buf();
loop {
if followed == MAX_LINKS_FOLLOWED {
return Err(Error::new(ErrorKind::InvalidInput, "maximum links followed"));
}
match fs::metadata(&result) {
Err(e) => return Err(e),
Ok(ref m) if !m.file_type().is_symlink() => break,
Ok(..) => {
followed += 1;
match fs::read_link(&result) {
Ok(path) => {
result.pop();
result.push(path);
},
Err(e) => {
return Err(e);
}
}
}
}
}
Ok(result)
}
#[allow(dead_code)]
pub fn canonicalize<P: AsRef<Path>>(original: P, can_mode: CanonicalizeMode) -> Result<PathBuf> {
// Create an absolute path
let original = original.as_ref();
let original = if original.is_absolute() {
original.to_path_buf()
} else {
env::current_dir().unwrap().join(original)
};
let mut result = PathBuf::new();
let mut parts = vec!();
// Split path by directory separator; add prefix (Windows-only) and root
// directory to final path buffer; add remaining parts to temporary
// vector for canonicalization.
for part in original.components() {
match part {
Component::Prefix(_) | Component::RootDir => {
result.push(part.as_os_str());
},
Component::CurDir => {},
Component::ParentDir => {
parts.pop();
},
Component::Normal(_) => {
parts.push(part.as_os_str());
}
}
}
// Resolve the symlinks where possible
if parts.len() > 0 {
for part in parts[..parts.len()-1].iter() {
result.push(part);
if can_mode == CanonicalizeMode::None {
continue;
}
match resolve(&result) {
Err(e) => match can_mode {
CanonicalizeMode::Missing => continue,
_ => return Err(e)
},
Ok(path) => {
result.pop();
result.push(path);
}
}
}
result.push(parts.last().unwrap());
match resolve(&result) {
Err(e) => { if can_mode == CanonicalizeMode::Existing { return Err(e); } },
Ok(path) => {
result.pop();
result.push(path);
}
}
}
Ok(result)
}

View file

@ -1,5 +1,4 @@
#![crate_name = "cp"]
#![feature(fs_canonicalize)]
/*
* This file is part of the uutils coreutils package.
@ -24,7 +23,7 @@ mod util;
#[path = "../common/filesystem.rs"]
mod filesystem;
use filesystem::UUPathExt;
use filesystem::{canonicalize, CanonicalizeMode, UUPathExt};
#[derive(Clone, Eq, PartialEq)]
pub enum Mode {
@ -155,8 +154,8 @@ fn copy(matches: getopts::Matches) {
pub fn paths_refer_to_same_file(p1: &Path, p2: &Path) -> Result<bool> {
// We have to take symlinks and relative paths into account.
let pathbuf1 = try!(fs::canonicalize(p1));
let pathbuf2 = try!(fs::canonicalize(p2));
let pathbuf1 = try!(canonicalize(p1, CanonicalizeMode::Normal));
let pathbuf2 = try!(canonicalize(p2, CanonicalizeMode::Normal));
Ok(pathbuf1 == pathbuf2)
}

View file

@ -11,120 +11,22 @@
extern crate getopts;
use std::env;
use std::fs::{metadata, read_link};
use std::io::{Error, ErrorKind, Result, Write};
use std::path::{Component, PathBuf};
use CanonicalizeMode::{None, Normal, Existing, Missing};
use std::fs;
use std::io::Write;
use std::path::PathBuf;
#[path = "../common/util.rs"]
#[macro_use]
mod util;
#[path = "../common/filesystem.rs"]
mod filesystem;
use filesystem::{canonicalize, CanonicalizeMode};
const NAME: &'static str = "readlink";
const VERSION: &'static str = "0.0.1";
#[derive(PartialEq)]
enum CanonicalizeMode {
None,
Normal,
Existing,
Missing,
}
fn resolve(original: &PathBuf) -> Result<PathBuf> {
const MAX_LINKS_FOLLOWED: u32 = 255;
let mut followed = 0;
let mut result = original.clone();
loop {
if followed == MAX_LINKS_FOLLOWED {
return Err(Error::new(ErrorKind::InvalidInput, "maximum links followed"));
}
match metadata(&result) {
Err(e) => return Err(e),
Ok(ref m) if !m.file_type().is_symlink() => break,
Ok(..) => {
followed += 1;
match read_link(&result) {
Ok(path) => {
result.pop();
result.push(path);
},
Err(e) => {
return Err(e);
}
}
}
}
}
Ok(result)
}
fn canonicalize(original: &PathBuf, can_mode: &CanonicalizeMode) -> Result<PathBuf> {
// Create an absolute path
let original = if original.as_path().is_absolute() {
original.clone()
} else {
env::current_dir().unwrap().join(original)
};
let mut result = PathBuf::new();
let mut parts = vec!();
// Split path by directory separator; add prefix (Windows-only) and root
// directory to final path buffer; add remaining parts to temporary
// vector for canonicalization.
for part in original.components() {
match part {
Component::Prefix(_) | Component::RootDir => {
result.push(part.as_os_str());
},
Component::CurDir => {},
Component::ParentDir => {
parts.pop();
},
Component::Normal(_) => {
parts.push(part.as_os_str());
}
}
}
// Resolve the symlinks where possible
if parts.len() > 0 {
for part in parts[..parts.len()-1].iter() {
result.push(part);
if *can_mode == None {
continue;
}
match resolve(&result) {
Err(e) => match *can_mode {
Missing => continue,
_ => return Err(e)
},
Ok(path) => {
result.pop();
result.push(path);
}
}
}
result.push(parts.last().unwrap());
match resolve(&result) {
Err(e) => { if *can_mode == Existing { return Err(e); } },
Ok(path) => {
result.pop();
result.push(path);
}
}
}
Ok(result)
}
pub fn uumain(args: Vec<String>) -> i32 {
let mut opts = getopts::Options::new();
@ -164,17 +66,17 @@ pub fn uumain(args: Vec<String>) -> i32 {
let silent = matches.opt_present("silent") || matches.opt_present("quiet");
let verbose = matches.opt_present("verbose");
let mut can_mode = None;
let mut can_mode = CanonicalizeMode::None;
if matches.opt_present("canonicalize") {
can_mode = Normal;
can_mode = CanonicalizeMode::Normal;
}
if matches.opt_present("canonicalize-existing") {
can_mode = Existing;
can_mode = CanonicalizeMode::Existing;
}
if matches.opt_present("canonicalize-missing") {
can_mode = Missing;
can_mode = CanonicalizeMode::Missing;
}
let files = matches.free;
@ -191,8 +93,8 @@ pub fn uumain(args: Vec<String>) -> i32 {
for f in files.iter() {
let p = PathBuf::from(f);
if can_mode == None {
match read_link(&p) {
if can_mode == CanonicalizeMode::None {
match fs::read_link(&p) {
Ok(path) => show(&path, no_newline, use_zero),
Err(err) => {
if verbose {
@ -202,7 +104,7 @@ pub fn uumain(args: Vec<String>) -> i32 {
}
}
} else {
match canonicalize(&p, &can_mode) {
match canonicalize(&p, can_mode) {
Ok(path) => show(&path, no_newline, use_zero),
Err(err) => {
if verbose {

View file

@ -1,5 +1,4 @@
#![crate_name= "realpath"]
#![feature(fs_canonicalize)]
/*
* This file is part of the uutils coreutils package.
@ -17,7 +16,14 @@ use std::fs;
use std::io::Write;
use std::path::{Path, PathBuf};
#[path = "../common/util.rs"] #[macro_use] mod util;
#[path = "../common/util.rs"]
#[macro_use]
mod util;
#[path = "../common/filesystem.rs"]
mod filesystem;
use filesystem::{canonicalize, CanonicalizeMode};
static NAME: &'static str = "realpath";
static VERSION: &'static str = "1.0.0";
@ -63,7 +69,7 @@ pub fn uumain(args: Vec<String>) -> i32 {
fn resolve_path(path: &str, strip: bool, zero: bool, quiet: bool) -> bool {
let p = Path::new(path).to_path_buf();
let abs = fs::canonicalize(p).unwrap();
let abs = canonicalize(p, CanonicalizeMode::Normal).unwrap();
if strip {
if zero {

View file

@ -1,5 +1,4 @@
#![crate_name = "relpath"]
#![feature(fs_canonicalize)]
/*
* This file is part of the uutils coreutils package.
@ -14,11 +13,17 @@ extern crate getopts;
extern crate libc;
use std::env;
use std::fs;
use std::io::Write;
use std::path::{Path, PathBuf};
#[path = "../common/util.rs"] #[macro_use] mod util;
#[path = "../common/util.rs"]
#[macro_use]
mod util;
#[path = "../common/filesystem.rs"]
mod filesystem;
use filesystem::{canonicalize, CanonicalizeMode};
static NAME: &'static str = "relpath";
static VERSION: &'static str = "1.0.0";
@ -54,12 +59,12 @@ pub fn uumain(args: Vec<String>) -> i32 {
} else {
env::current_dir().unwrap()
};
let absto = fs::canonicalize(to).unwrap();
let absfrom = fs::canonicalize(from).unwrap();
let absto = canonicalize(to, CanonicalizeMode::Normal).unwrap();
let absfrom = canonicalize(from, CanonicalizeMode::Normal).unwrap();
if matches.opt_present("d") {
let base = Path::new(&matches.opt_str("d").unwrap()).to_path_buf();
let absbase = fs::canonicalize(base).unwrap();
let absbase = canonicalize(base, CanonicalizeMode::Normal).unwrap();
if !absto.as_path().starts_with(absbase.as_path()) || !absfrom.as_path().starts_with(absbase.as_path()) {
println!("{}", absto.display());
return 0

View file

@ -1,5 +1,5 @@
#![crate_name = "stdbuf"]
#![feature(fs_canonicalize, negate_unsigned)]
#![feature(negate_unsigned)]
/*
* This file is part of the uutils coreutils package.
@ -15,7 +15,6 @@ extern crate libc;
use getopts::{Matches, Options};
use std::env;
use std::fs;
use std::io::{self, Write};
use std::os::unix::process::ExitStatusExt;
use std::path::PathBuf;
@ -28,7 +27,7 @@ mod util;
#[path = "../common/filesystem.rs"]
mod filesystem;
use filesystem::UUPathExt;
use filesystem::{canonicalize, CanonicalizeMode, UUPathExt};
static NAME: &'static str = "stdbuf";
static VERSION: &'static str = "1.0.0";
@ -195,7 +194,7 @@ fn set_command_env(command: &mut Command, buffer_name: &str, buffer_type: Buffer
fn exe_path() -> io::Result<PathBuf> {
let exe_path = try!(env::current_exe());
let absolute_path = try!(fs::canonicalize(exe_path.as_path()));
let absolute_path = try!(canonicalize(exe_path, CanonicalizeMode::Normal));
Ok(match absolute_path.parent() {
Some(p) => p.to_path_buf(),
None => absolute_path.clone()

View file

@ -1 +1 @@
DEPLIBS += bit-vec bit-set
DEPLIBS += bit-vec bit-set vec_map

View file

@ -1,5 +1,5 @@
#![crate_name = "tr"]
#![feature(io, vecmap)]
#![feature(io)]
/*
* This file is part of the uutils coreutils package.
@ -14,11 +14,12 @@
extern crate bit_set;
extern crate getopts;
extern crate vec_map;
use bit_set::BitSet;
use getopts::Options;
use std::collections::VecMap;
use std::io::{stdin, stdout, BufReader, Read, Write};
use vec_map::VecMap;
use expand::ExpandSet;