mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-07-28 11:37:44 +00:00
remove cat warning, update makefile
This commit is contained in:
parent
d0c2896b16
commit
fc1da5a691
4 changed files with 105 additions and 20 deletions
1
Makefile
1
Makefile
|
@ -31,6 +31,7 @@ EXES := \
|
||||||
# Programs with usable tests
|
# Programs with usable tests
|
||||||
TEST_PROGS := \
|
TEST_PROGS := \
|
||||||
cat \
|
cat \
|
||||||
|
mkdir \
|
||||||
|
|
||||||
TEST ?= $(TEST_PROGS)
|
TEST ?= $(TEST_PROGS)
|
||||||
|
|
||||||
|
|
|
@ -86,6 +86,7 @@ pub enum NumberingMode {
|
||||||
}
|
}
|
||||||
|
|
||||||
static TAB: u8 = '\t' as u8;
|
static TAB: u8 = '\t' as u8;
|
||||||
|
#[allow(dead_code)]
|
||||||
static CR: u8 = '\r' as u8;
|
static CR: u8 = '\r' as u8;
|
||||||
static LF: u8 = '\n' as u8;
|
static LF: u8 = '\n' as u8;
|
||||||
|
|
||||||
|
|
118
mkdir/mkdir.rs
118
mkdir/mkdir.rs
|
@ -1,6 +1,6 @@
|
||||||
#[crate_id(name="mkdir", vers="1.0.0", author="Nicholas Juszczak")];
|
#[crate_id(name="mkdir", vers="1.0.0", author="Nicholas Juszczak")];
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* This file is part of the uutils coreutils package.
|
* This file is part of the uutils coreutils package.
|
||||||
*
|
*
|
||||||
* (c) Nicholas Juszczak <juszczakn@gmail.com>
|
* (c) Nicholas Juszczak <juszczakn@gmail.com>
|
||||||
|
@ -12,20 +12,23 @@
|
||||||
extern mod extra;
|
extern mod extra;
|
||||||
|
|
||||||
use std::os;
|
use std::os;
|
||||||
use std::io::stderr;
|
use std::io::{fs, result, stderr};
|
||||||
|
use std::num::strconv;
|
||||||
use extra::getopts::groups;
|
use extra::getopts::groups;
|
||||||
use std::io::fs;
|
|
||||||
|
|
||||||
static VERSION: &'static str = "1.0.0";
|
static VERSION: &'static str = "1.0.0";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles option parsing
|
||||||
|
*/
|
||||||
fn main() {
|
fn main() {
|
||||||
let args: ~[~str] = os::args();
|
let args: ~[~str] = os::args();
|
||||||
|
|
||||||
let opts: ~[groups::OptGroup] = ~[
|
let opts: ~[groups::OptGroup] = ~[
|
||||||
// Linux-specific options
|
// Linux-specific options, not implemented
|
||||||
// groups::optflag("m", "mode", "set file mode"),
|
|
||||||
// groups::optflag("Z", "context", "set SELinux secutiry context" +
|
// groups::optflag("Z", "context", "set SELinux secutiry context" +
|
||||||
// " of each created directory to CTX"),
|
// " of each created directory to CTX"),
|
||||||
|
groups::optopt("m", "mode", "set file mode", "755"),
|
||||||
groups::optflag("p", "parents", "make parent directories as needed"),
|
groups::optflag("p", "parents", "make parent directories as needed"),
|
||||||
groups::optflag("v", "verbose",
|
groups::optflag("v", "verbose",
|
||||||
"print a message for each printed directory"),
|
"print a message for each printed directory"),
|
||||||
|
@ -43,7 +46,7 @@ fn main() {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if matches.opt_present("help") {
|
if args.len() == 1 || matches.opt_present("help") {
|
||||||
print_help(opts);
|
print_help(opts);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -51,10 +54,35 @@ fn main() {
|
||||||
println("mkdir v" + VERSION);
|
println("mkdir v" + VERSION);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
let mut verbose_flag: bool = false;
|
||||||
|
if matches.opt_present("verbose") {
|
||||||
|
verbose_flag = true;
|
||||||
|
}
|
||||||
|
|
||||||
let mk_parents: bool = matches.opt_present("parents");
|
let mk_parents: bool = matches.opt_present("parents");
|
||||||
|
|
||||||
|
// Translate a ~str in octal form to u32, default to 755
|
||||||
|
// Not tested on Windows
|
||||||
|
let mode_match = matches.opts_str(&[~"mode"]);
|
||||||
|
let mode: u32 = if mode_match.is_some() {
|
||||||
|
let m: ~str = mode_match.unwrap();
|
||||||
|
let res = strconv::from_str_common(m, 8, false, false, false,
|
||||||
|
strconv::ExpNone,
|
||||||
|
false, false);
|
||||||
|
if res.is_some() {
|
||||||
|
res.unwrap()
|
||||||
|
} else {
|
||||||
|
writeln!(&mut stderr() as &mut Writer,
|
||||||
|
"Error: no mode given");
|
||||||
|
os::set_exit_status(1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
0o755
|
||||||
|
};
|
||||||
|
|
||||||
let dirs: ~[~str] = matches.free;
|
let dirs: ~[~str] = matches.free;
|
||||||
mkdir(dirs, mk_parents);
|
exec(dirs, mk_parents, mode, verbose_flag);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn print_help(opts: &[groups::OptGroup]) {
|
fn print_help(opts: &[groups::OptGroup]) {
|
||||||
|
@ -65,27 +93,79 @@ fn print_help(opts: &[groups::OptGroup]) {
|
||||||
" if they do not exist", opts));
|
" if they do not exist", opts));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* std::libc currently does not provide bindings for any bits
|
/**
|
||||||
besides user bits, so might as well use octal for now.
|
* Create the list of new directories
|
||||||
See 'std::io::FilePermission',
|
*/
|
||||||
'std::libc::consts::os::posix88' for future updates */
|
fn exec(dirs: ~[~str], mk_parents: bool, mode: u32, verbose: bool) {
|
||||||
fn mkdir(dirs: ~[~str], mk_parents: bool) {
|
let mut parent_dirs: ~[~str] = ~[];
|
||||||
let default: u32 = 0o755;
|
|
||||||
|
|
||||||
for dir in dirs.iter() {
|
for dir in dirs.iter() {
|
||||||
let path = Path::new((*dir).clone());
|
let path = Path::new((*dir).clone());
|
||||||
// Recursively create parent dirs as needed
|
// Build list of parent dirs which need to be created
|
||||||
if mk_parents {
|
if mk_parents {
|
||||||
match path.dirname_str() {
|
match path.dirname_str() {
|
||||||
Some(p) => if p != "." {
|
Some(p) => if p != "." {
|
||||||
mkdir(~[p.into_owned()], mk_parents)
|
parent_dirs.push(p.into_owned())
|
||||||
},
|
},
|
||||||
None => ()
|
None => ()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if !path.exists() {
|
}
|
||||||
println(*dir);
|
// Recursively build parent dirs that are needed
|
||||||
fs::mkdir(&path, default);
|
if !parent_dirs.is_empty() {
|
||||||
|
exec(parent_dirs, mk_parents, mode, verbose);
|
||||||
|
}
|
||||||
|
|
||||||
|
for dir in dirs.iter() {
|
||||||
|
let path = Path::new((*dir).clone());
|
||||||
|
// Determine if parent directory to the one to
|
||||||
|
// be created exists
|
||||||
|
let parent: &str = match path.dirname_str() {
|
||||||
|
Some(p) => p,
|
||||||
|
None => ""
|
||||||
|
};
|
||||||
|
let parent_exists:bool = Path::new(parent).exists();
|
||||||
|
if parent_exists && !path.exists() {
|
||||||
|
// if mkdir failed return
|
||||||
|
if !mkdir(&path, mode) {return;}
|
||||||
|
if verbose {println(*dir);}
|
||||||
|
} else {
|
||||||
|
let mut error_msg: ~str = ~"";
|
||||||
|
if !parent_exists {
|
||||||
|
error_msg.push_str("Error: parent directory '");
|
||||||
|
error_msg.push_str(parent);
|
||||||
|
error_msg.push_str("' does not exist");
|
||||||
|
} else {
|
||||||
|
error_msg.push_str("Error: directory '");
|
||||||
|
error_msg.push_str(*dir);
|
||||||
|
error_msg.push_str("' already exists");
|
||||||
|
}
|
||||||
|
writeln!(&mut stderr() as &mut Writer,
|
||||||
|
"{}", error_msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wrapper to catch errors, return false if failed
|
||||||
|
*/
|
||||||
|
fn mkdir(path: &Path, mode: u32) -> bool {
|
||||||
|
match result(|| fs::mkdir(path, mode)) {
|
||||||
|
Ok(_) => true,
|
||||||
|
Err(e) => {
|
||||||
|
writeln!(&mut stderr() as &mut Writer,
|
||||||
|
"mkdir: test {}", e.to_str());
|
||||||
|
os::set_exit_status(1);
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// #[test]
|
||||||
|
// fn create_dir() {
|
||||||
|
// let test_dir = "mkdir_test_dir";
|
||||||
|
// let path: Path = Path::new(test_dir);
|
||||||
|
// let mode: u32 = 0x755;
|
||||||
|
// let result = mkdir(&path, mode);
|
||||||
|
// fs::rmdir(&path);
|
||||||
|
// assert_eq!(true, result);
|
||||||
|
// }
|
||||||
|
|
3
mkdir/test.rs
Normal file
3
mkdir/test.rs
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
fn main() {
|
||||||
|
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue