From 8fbfe24176df6f8b10b02188786413da9d84c41f Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Sun, 8 Jun 2014 18:49:06 -0700 Subject: [PATCH] Make show_error! not set the exit code. #211 --- cksum/cksum.rs | 10 ++++++-- common/util.rs | 16 +++--------- du/du.rs | 4 +-- groups/groups.rs | 4 +-- hostid/hostid.rs | 6 ++--- kill/kill.rs | 12 ++++----- mkdir/mkdir.rs | 2 +- rm/rm.rs | 60 +++++++++++++++++++++++++++++++------------- rmdir/rmdir.rs | 48 ++++++++++++++++++++++++----------- seq/seq.rs | 10 ++++---- sleep/sleep.rs | 9 ++++--- tr/tr.rs | 8 +++--- truncate/truncate.rs | 46 ++++++++++++++++++--------------- wc/wc.rs | 25 ++++++++++-------- 14 files changed, 156 insertions(+), 104 deletions(-) diff --git a/cksum/cksum.rs b/cksum/cksum.rs index af6799437..e8dbf4aa7 100644 --- a/cksum/cksum.rs +++ b/cksum/cksum.rs @@ -111,7 +111,10 @@ pub fn uumain(args: Vec) -> int { if files.is_empty() { match cksum("-") { Ok((crc, size)) => println!("{} {}", crc, size), - Err(err) => show_error!(2, "{}", err), + Err(err) => { + show_errer!("{}", err); + return 2; + } } return 0; } @@ -119,7 +122,10 @@ pub fn uumain(args: Vec) -> int { for fname in files.iter() { match cksum(fname.as_slice()) { Ok((crc, size)) => println!("{} {} {}", crc, size, fname), - Err(err) => show_error!(2, "'{}' {}", fname, err), + Err(err) => { + show_errer!("'{}' {}", fname, err); + return 2; + } } } diff --git a/common/util.rs b/common/util.rs index 401bad4cc..dc12fd26c 100644 --- a/common/util.rs +++ b/common/util.rs @@ -12,18 +12,7 @@ extern crate libc; #[macro_export] -macro_rules! show_error( - ($exitcode:expr, $($args:expr),+) => ({ - ::std::os::set_exit_status($exitcode as int); - safe_write!(&mut ::std::io::stderr(), "{}: error: ", ::NAME); - safe_writeln!(&mut ::std::io::stderr(), $($args),+); - }) -) - -// FIXME #211: Transitional until there are no further users of `show_error!`. -// Then this can be renamed. -#[macro_export] -macro_rules! display_error( +macro_rules! show_errer( ($($args:expr),+) => ({ safe_write!(&mut ::std::io::stderr(), "{}: error: ", ::NAME); safe_writeln!(&mut ::std::io::stderr(), $($args),+); @@ -41,7 +30,8 @@ macro_rules! show_warning( #[macro_export] macro_rules! crash( ($exitcode:expr, $($args:expr),+) => ({ - show_error!($exitcode, $($args),+); + safe_write!(&mut ::std::io::stderr(), "{}: error: ", ::NAME); + safe_writeln!(&mut ::std::io::stderr(), $($args),+); unsafe { self::libc::exit($exitcode as self::libc::c_int); } }) ) diff --git a/du/du.rs b/du/du.rs index 0b57be8f0..a8cdf00ce 100644 --- a/du/du.rs +++ b/du/du.rs @@ -162,8 +162,8 @@ pub fn uumain(args: Vec) -> int { let matches = match getopts::getopts(args.tail(), opts) { Ok(m) => m, Err(f) => { - show_error!(1, "Invalid options\n{}", f.to_err_msg()); - return 0; + show_errer!("Invalid options\n{}", f.to_err_msg()); + return 1; } }; diff --git a/groups/groups.rs b/groups/groups.rs index 54abdbc92..47181bc32 100644 --- a/groups/groups.rs +++ b/groups/groups.rs @@ -36,8 +36,8 @@ pub fn uumain(args: Vec) -> int { let matches = match getopts(args.tail(), options) { Ok(m) => { m }, Err(_) => { - show_error!(1, "{}", usage(NAME, options)); - return 0; + show_errer!("{}", usage(NAME, options)); + return 1; } }; diff --git a/hostid/hostid.rs b/hostid/hostid.rs index 38aaefd24..e89875051 100644 --- a/hostid/hostid.rs +++ b/hostid/hostid.rs @@ -36,7 +36,7 @@ mod util; static NAME: &'static str = "hostid"; static VERSION: &'static str = "0.0.1"; -static EXIT_ERR: i32 = 1; +static EXIT_ERR: int = 1; pub enum Mode { HostId, @@ -65,8 +65,8 @@ pub fn uumain(args: Vec) -> int { let matches = match getopts(args.tail(), opts) { Ok(m) => m, Err(e) => { - show_error!(EXIT_ERR, "{}\n{}", e.to_err_msg(), get_help_text(NAME, usage.as_slice())); - return 0; + show_errer!("{}\n{}", e.to_err_msg(), get_help_text(NAME, usage.as_slice())); + return EXIT_ERR; }, }; diff --git a/kill/kill.rs b/kill/kill.rs index 0e48b6306..22d73fc8a 100644 --- a/kill/kill.rs +++ b/kill/kill.rs @@ -41,8 +41,8 @@ mod util; static NAME: &'static str = "kill"; static VERSION: &'static str = "0.0.1"; -static EXIT_OK: i32 = 0; -static EXIT_ERR: i32 = 1; +static EXIT_OK: int = 0; +static EXIT_ERR: int = 1; pub enum Mode { Kill, @@ -71,8 +71,8 @@ pub fn uumain(args: Vec) -> int { let matches = match getopts(args.tail(), opts) { Ok(m) => m, Err(e) => { - show_error!(EXIT_ERR, "{}\n{}", e.to_err_msg(), get_help_text(NAME, usage.as_slice())); - return 0 + show_errer!("{}\n{}", e.to_err_msg(), get_help_text(NAME, usage.as_slice())); + return EXIT_ERR; }, }; @@ -128,10 +128,10 @@ fn print_signal(signal_name_or_value: &str) { for signal in ALL_SIGNALS.iter() { if signal.name == signal_name_or_value || (format!("SIG{}", signal.name).as_slice()) == signal_name_or_value { println!("{}", signal.value) - exit!(EXIT_OK) + exit!(EXIT_OK as i32) } else if signal_name_or_value == signal.value.to_str().as_slice() { println!("{}", signal.name); - exit!(EXIT_OK) + exit!(EXIT_OK as i32) } } crash!(EXIT_ERR, "unknown signal name {}", signal_name_or_value) diff --git a/mkdir/mkdir.rs b/mkdir/mkdir.rs index 288591e42..1e877c089 100644 --- a/mkdir/mkdir.rs +++ b/mkdir/mkdir.rs @@ -144,7 +144,7 @@ fn exec(dirs: Vec, mk_parents: bool, mode: FilePermission, verbose: bool } else { format!("directory '{}' already exists", *dir) }; - display_error!("{}", error_msg); + show_errer!("{}", error_msg); return Err(1); } } diff --git a/rm/rm.rs b/rm/rm.rs index 44f46e5d6..7f24fe202 100644 --- a/rm/rm.rs +++ b/rm/rm.rs @@ -79,8 +79,9 @@ pub fn uumain(args: Vec) -> int { } else if matches.opt_present("version") { println!("rm 1.0.0"); } else if matches.free.is_empty() { - show_error!(1, "missing an argument"); - show_error!(1, "for help, try '{0:s} --help'", program) + show_errer!("missing an argument"); + show_errer!("for help, try '{0:s} --help'", program); + return 0; } else { let force = matches.opt_present("force"); let interactive = @@ -116,15 +117,18 @@ pub fn uumain(args: Vec) -> int { return 0; } } - remove(matches.free, force, interactive, one_fs, preserve_root, - recursive, dir, verbose); + match remove(matches.free, force, interactive, one_fs, preserve_root, + recursive, dir, verbose) { + Ok(()) => ( /* pass */ ), + Err(e) => return e + } } return 0; } // TODO: implement one-file-system -fn remove(files: Vec, force: bool, interactive: InteractiveMode, one_fs: bool, preserve_root: bool, recursive: bool, dir: bool, verbose: bool) { +fn remove(files: Vec, force: bool, interactive: InteractiveMode, one_fs: bool, preserve_root: bool, recursive: bool, dir: bool, verbose: bool) -> Result<(), int> { for filename in files.iter() { let filename = filename.as_slice(); let file = Path::new(filename); @@ -137,30 +141,46 @@ fn remove(files: Vec, force: bool, interactive: InteractiveMode, one_fs: crash!(1, "{}", f.to_str()); } }; - remove(walk_dir.map(|x| x.as_str().unwrap().to_string()).collect(), force, interactive, one_fs, preserve_root, recursive, dir, verbose); - remove_dir(&file, filename, interactive, verbose); + match remove(walk_dir.map(|x| x.as_str().unwrap().to_string()).collect(), force, interactive, one_fs, preserve_root, recursive, dir, verbose) { + Ok(()) => ( /* pass */ ), + Err(e) => return Err(e) + } + match remove_dir(&file, filename, interactive, verbose) { + Ok(()) => ( /* pass */ ), + Err(e) => return Err(e) + } } else if dir && (filename != "/" || !preserve_root) { - remove_dir(&file, filename, interactive, verbose); + match remove_dir(&file, filename, interactive, verbose) { + Ok(()) => ( /* pass */ ), + Err(e) => return Err(e) + } } else { if recursive { - show_error!(1, "could not remove directory '{}'", + show_errer!("could not remove directory '{}'", filename); + return Err(1); } else { - show_error!(1, - "could not remove directory '{}' (did you mean to pass '-r'?)", + show_errer!("could not remove directory '{}' (did you mean to pass '-r'?)", filename); + return Err(1); } } } else { - remove_file(&file, filename.as_slice(), interactive, verbose); + match remove_file(&file, filename.as_slice(), interactive, verbose) { + Ok(()) => ( /* pass */ ), + Err(e) => return Err(e) + } } } else if !force { - show_error!(1, "no such file or directory '{}'", filename); + show_errer!("no such file or directory '{}'", filename); + return Err(1); } } + + return Ok(()); } -fn remove_dir(path: &Path, name: &str, interactive: InteractiveMode, verbose: bool) { +fn remove_dir(path: &Path, name: &str, interactive: InteractiveMode, verbose: bool) -> Result<(), int> { let response = if interactive == InteractiveAlways { prompt_file(path, name) @@ -171,13 +191,16 @@ fn remove_dir(path: &Path, name: &str, interactive: InteractiveMode, verbose: bo match fs::rmdir(path) { Ok(_) => if verbose { println!("Removed '{}'", name); }, Err(f) => { - show_error!(1, "{}", f.to_str()); + show_errer!("{}", f.to_str()); + return Err(1); } } } + + return Ok(()); } -fn remove_file(path: &Path, name: &str, interactive: InteractiveMode, verbose: bool) { +fn remove_file(path: &Path, name: &str, interactive: InteractiveMode, verbose: bool) -> Result<(), int> { let response = if interactive == InteractiveAlways { prompt_file(path, name) @@ -188,10 +211,13 @@ fn remove_file(path: &Path, name: &str, interactive: InteractiveMode, verbose: b match fs::unlink(path) { Ok(_) => if verbose { println!("Removed '{}'", name); }, Err(f) => { - show_error!(1, "{}", f.to_str()); + show_errer!("{}", f.to_str()); + return Err(1); } } } + + return Ok(()); } fn prompt_file(path: &Path, name: &str) -> bool { diff --git a/rmdir/rmdir.rs b/rmdir/rmdir.rs index cd9020900..05648e3d8 100644 --- a/rmdir/rmdir.rs +++ b/rmdir/rmdir.rs @@ -38,8 +38,8 @@ pub fn uumain(args: Vec) -> int { let matches = match getopts::getopts(args.tail(), opts) { Ok(m) => m, Err(f) => { - show_error!(1, "{}", f.to_err_msg()); - return 0; + show_errer!("{}", f.to_err_msg()); + return 1; } }; @@ -53,39 +53,50 @@ pub fn uumain(args: Vec) -> int { } else if matches.opt_present("version") { println!("rmdir 1.0.0"); } else if matches.free.is_empty() { - show_error!(1, "missing an argument"); - show_error!(1, "for help, try '{0:s} --help'", program); + show_errer!("missing an argument"); + show_errer!("for help, try '{0:s} --help'", program); + return 1; } else { let ignore = matches.opt_present("ignore-fail-on-non-empty"); let parents = matches.opt_present("parents"); let verbose = matches.opt_present("verbose"); - remove(matches.free, ignore, parents, verbose); + match remove(matches.free, ignore, parents, verbose) { + Ok(()) => ( /* pass */ ), + Err(e) => return e + } } return 0; } -fn remove(dirs: Vec, ignore: bool, parents: bool, verbose: bool) { +fn remove(dirs: Vec, ignore: bool, parents: bool, verbose: bool) -> Result<(), int>{ for dir in dirs.iter() { let path = Path::new(dir.as_slice()); if path.exists() { if path.is_dir() { - remove_dir(&path, dir.as_slice(), ignore, parents, verbose); + match remove_dir(&path, dir.as_slice(), ignore, parents, verbose) { + Ok(()) => ( /* pass */ ), + Err(e) => return Err(e) + } } else { - show_error!(1, "failed to remove '{}' (file)", *dir); + show_errer!("failed to remove '{}' (file)", *dir); + return Err(1); } } else { - show_error!(1, "no such file or directory '{}'", *dir); + show_errer!("no such file or directory '{}'", *dir); + return Err(1); } } + + return Ok(()); } -fn remove_dir(path: &Path, dir: &str, ignore: bool, parents: bool, verbose: bool) { +fn remove_dir(path: &Path, dir: &str, ignore: bool, parents: bool, verbose: bool) -> Result<(), int> { let mut walk_dir = match fs::walk_dir(path) { Ok(m) => m, Err(f) => { - show_error!(1, "{}", f.to_str()); - return; + show_errer!("{}", f.to_str()); + return Err(1); } }; if walk_dir.next() == None { @@ -97,16 +108,23 @@ fn remove_dir(path: &Path, dir: &str, ignore: bool, parents: bool, verbose: bool if parents { let dirname = path.dirname_str().unwrap(); if dirname != "." { - remove_dir(&Path::new(dirname), dirname, ignore, parents, verbose); + match remove_dir(&Path::new(dirname), dirname, ignore, parents, verbose) { + Ok(()) => ( /* pass */ ), + Err(e) => return Err(e) + } } } } Err(f) => { - show_error!(1, "{}", f.to_str()); + show_errer!("{}", f.to_str()); + return Err(1); } } } else if !ignore { - show_error!(1, "Failed to remove directory '{}' (non-empty)", dir); + show_errer!("Failed to remove directory '{}' (non-empty)", dir); + return Err(1); } + + return Ok(()); } diff --git a/seq/seq.rs b/seq/seq.rs index f0d068a87..2f3f48c5b 100644 --- a/seq/seq.rs +++ b/seq/seq.rs @@ -47,9 +47,9 @@ pub fn uumain(args: Vec) -> int { let matches = match getopts::getopts(args.tail(), opts) { Ok(m) => { m } Err(f) => { - show_error!(1, "{:s}", f.to_err_msg()); + show_errer!("{:s}", f.to_err_msg()); print_usage(opts); - return 0; + return 1; } }; if matches.opt_present("help") { @@ -67,7 +67,7 @@ pub fn uumain(args: Vec) -> int { let first = if matches.free.len() > 1 { match parse_float(matches.free.get(0).as_slice()) { Ok(n) => n, - Err(s) => { show_error!(1, "{:s}", s); return 0; } + Err(s) => { show_errer!("{:s}", s); return 1; } } } else { 1.0 @@ -75,14 +75,14 @@ pub fn uumain(args: Vec) -> int { let step = if matches.free.len() > 2 { match parse_float(matches.free.get(1).as_slice()) { Ok(n) => n, - Err(s) => { show_error!(1, "{:s}", s); return 0; } + Err(s) => { show_errer!("{:s}", s); return 1; } } } else { 1.0 }; let last = match parse_float(matches.free.get(matches.free.len()-1).as_slice()) { Ok(n) => n, - Err(s) => { show_error!(1, "{:s}", s); return 0; } + Err(s) => { show_errer!("{:s}", s); return 1; } }; let separator = escape_sequences(matches.opt_str("s").unwrap_or("\n".to_string()).as_slice()); let terminator = escape_sequences(matches.opt_str("t").unwrap_or(separator.to_string()).as_slice()); diff --git a/sleep/sleep.rs b/sleep/sleep.rs index 64c3f0828..0a5253ecc 100644 --- a/sleep/sleep.rs +++ b/sleep/sleep.rs @@ -36,8 +36,8 @@ pub fn uumain(args: Vec) -> int { let matches = match getopts::getopts(args.tail(), opts) { Ok(m) => m, Err(f) => { - show_error!(1, "{}", f.to_err_msg()); - return 0; + show_errer!("{}", f.to_err_msg()); + return 1; } }; @@ -57,8 +57,9 @@ specified by the sum of their values.", opts).as_slice()); } else if matches.opt_present("version") { println!("sleep 1.0.0"); } else if matches.free.is_empty() { - show_error!(1, "missing an argument"); - show_error!(1, "for help, try '{0:s} --help'", program); + show_errer!("missing an argument"); + show_errer!("for help, try '{0:s} --help'", program); + return 1; } else { sleep(matches.free); } diff --git a/tr/tr.rs b/tr/tr.rs index 48af9ed4a..3cc7a36e1 100644 --- a/tr/tr.rs +++ b/tr/tr.rs @@ -161,8 +161,8 @@ pub fn uumain(args: Vec) -> int { let matches = match getopts::getopts(args.tail(), opts) { Ok(m) => m, Err(err) => { - show_error!(1, "{}", err.to_err_msg()); - return 0; + show_errer!("{}", err.to_err_msg()); + return 1; } }; @@ -186,8 +186,8 @@ pub fn uumain(args: Vec) -> int { let sets = matches.free; if cflag && !dflag { - show_error!(1, "-c is only supported with -d"); - return 0; + show_errer!("-c is only supported with -d"); + return 1; } if dflag { diff --git a/truncate/truncate.rs b/truncate/truncate.rs index fd9f3dbea..4bf395af7 100644 --- a/truncate/truncate.rs +++ b/truncate/truncate.rs @@ -21,18 +21,6 @@ use std::u64; #[path = "../common/util.rs"] mod util; -macro_rules! get_file_size( - ($file:ident, $action:expr) => ({ - match fs::stat($file.path()) { - Ok(stat) => stat.size, - Err(f) => { - show_error!(1, "{}", f.to_str()); - $action - } - } - }) -) - #[deriving(Eq, PartialEq)] enum TruncateMode { Reference, @@ -95,8 +83,8 @@ file based on its current size: } else if matches.opt_present("version") { println!("truncate 1.0.0"); } else if matches.free.is_empty() { - show_error!(1, "missing an argument"); - crash!(1, "for help, try '{0:s} --help'", program); + show_errer!("missing an argument"); + return 1; } else { let no_create = matches.opt_present("no-create"); let io_blocks = matches.opt_present("io-blocks"); @@ -105,14 +93,17 @@ file based on its current size: if reference.is_none() && size.is_none() { crash!(1, "you must specify either --reference or --size"); } else { - truncate(no_create, io_blocks, reference, size, matches.free); + match truncate(no_create, io_blocks, reference, size, matches.free) { + Ok(()) => ( /* pass */ ), + Err(e) => return e + } } } return 0; } -fn truncate(no_create: bool, _: bool, reference: Option, size: Option, filenames: Vec) { +fn truncate(no_create: bool, _: bool, reference: Option, size: Option, filenames: Vec) -> Result<(), int> { let (refsize, mode) = match reference { Some(rfilename) => { let rfile = match File::open(&Path::new(rfilename.clone())) { @@ -121,7 +112,13 @@ fn truncate(no_create: bool, _: bool, reference: Option, size: Option (stat.size, Reference), + Err(f) => { + show_errer!("{}", f.to_str()); + return Err(1); + } + } } None => parse_size(size.unwrap().as_slice()) }; @@ -131,7 +128,13 @@ fn truncate(no_create: bool, _: bool, reference: Option, size: Option { - let fsize = get_file_size!(file, continue); + let fsize = match fs::stat(file.path()) { + Ok(stat) => stat.size, + Err(f) => { + show_warning!("{}", f.to_str()); + continue; + } + }; let tsize = match mode { Reference => refsize, Extend => fsize + refsize, @@ -144,16 +147,19 @@ fn truncate(no_create: bool, _: bool, reference: Option, size: Option {} Err(f) => { - show_error!(1, "{}", f.to_str()); + show_errer!("{}", f.to_str()); + return Err(1); } } } Err(f) => { - show_error!(1, "{}", f.to_str()); + show_errer!("{}", f.to_str()); + return Err(1); } } } } + return Ok(()); } fn parse_size(size: &str) -> (u64, TruncateMode) { diff --git a/wc/wc.rs b/wc/wc.rs index bfd4d1597..2905a9702 100644 --- a/wc/wc.rs +++ b/wc/wc.rs @@ -17,6 +17,7 @@ extern crate libc; use std::os; use std::str::from_utf8; use std::io::{print, stdin, File, BufferedReader}; +use StdResult = std::result::Result; use getopts::Matches; #[path = "../common/util.rs"] @@ -75,7 +76,10 @@ pub fn uumain(args: Vec) -> int { files = vec!("-".to_string()); } - wc(files, &matches); + match wc(files, &matches) { + Ok(()) => ( /* pass */ ), + Err(e) => return e + } return 0; } @@ -91,7 +95,7 @@ fn is_word_seperator(byte: u8) -> bool { byte == SPACE || byte == TAB || byte == CR || byte == SYN || byte == FF } -pub fn wc(files: Vec, matches: &Matches) { +pub fn wc(files: Vec, matches: &Matches) -> StdResult<(), int> { let mut total_line_count: uint = 0; let mut total_word_count: uint = 0; let mut total_char_count: uint = 0; @@ -103,8 +107,8 @@ pub fn wc(files: Vec, matches: &Matches) { for path in files.iter() { let mut reader = match open(path.to_string()) { - Some(f) => f, - None => { continue } + Ok(f) => f, + Err(e) => { return Err(e); } }; let mut line_count: uint = 0; @@ -187,6 +191,8 @@ pub fn wc(files: Vec, matches: &Matches) { if files.len() > 1 { print_stats("total", total_line_count, total_word_count, total_char_count, total_byte_count, total_longest_line_length, matches, max_str_len); } + + return Ok(()); } fn print_stats(filename: &str, line_count: uint, word_count: uint, char_count: uint, @@ -226,21 +232,20 @@ fn print_stats(filename: &str, line_count: uint, word_count: uint, char_count: u } } -fn open(path: String) -> Option>> { +fn open(path: String) -> StdResult>, int> { if "-" == path.as_slice() { let reader = box stdin() as Box; - return Some(BufferedReader::new(reader)); + return Ok(BufferedReader::new(reader)); } match File::open(&std::path::Path::new(path.as_slice())) { Ok(fd) => { let reader = box fd as Box; - return Some(BufferedReader::new(reader)); + return Ok(BufferedReader::new(reader)); }, Err(e) => { - show_error!(1, "wc: {0:s}: {1:s}", path, e.desc.to_str()); + show_errer!("wc: {0:s}: {1:s}", path, e.desc.to_str()); + return Err(1); } } - - None }