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:
commit
7c69b3a1fd
9 changed files with 155 additions and 137 deletions
1
deps/Cargo.toml
vendored
1
deps/Cargo.toml
vendored
|
@ -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"
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -1 +1 @@
|
|||
DEPLIBS += bit-vec bit-set
|
||||
DEPLIBS += bit-vec bit-set vec_map
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue