diff --git a/Makefile b/Makefile index 3a6bba447..8ef8504e8 100644 --- a/Makefile +++ b/Makefile @@ -145,6 +145,11 @@ build/busybox: build/uutils rm -f build/busybox ln -s $(SRC_DIR)/build/uutils build/busybox +# This is a busybox-specific config file their test suite wants to parse. +# For now it's blank. +build/.config: build/uutils + touch $@ + ifeq ($(BUSYBOX_SRC),) busytest: @echo @@ -153,7 +158,7 @@ busytest: @echo @false else -busytest: build/busybox +busytest: build/busybox build/.config (cd $(BUSYBOX_SRC)/testsuite && bindir=$(SRC_DIR)/build tstdir=$(BUSYBOX_SRC)/testsuite $(BUSYBOX_SRC)/testsuite/runtest $(RUNTEST_ARGS)) endif endif diff --git a/base64/base64.rs b/base64/base64.rs index fd240f5b4..91ee7bcbc 100644 --- a/base64/base64.rs +++ b/base64/base64.rs @@ -15,7 +15,7 @@ extern crate serialize; extern crate getopts; extern crate libc; -#[phase(syntax, link)] extern crate log; +#[phase(plugin, link)] extern crate log; use std::io::{println, File, stdin, stdout}; use std::os; @@ -35,7 +35,7 @@ mod util; static NAME: &'static str = "base64"; -pub fn uumain(args: Vec) { +pub fn uumain(args: Vec) -> int { let opts = [ optflag("d", "decode", "decode data"), optflag("i", "ignore-garbage", "when decoding, ignore non-alphabetic characters"), @@ -88,10 +88,12 @@ pub fn uumain(args: Vec) { Help => help(progname.as_slice(), usage.as_slice()), Version => version() } + + 0 } #[allow(dead_code)] -fn main() { uumain(os::args()); } +fn main() { os::set_exit_status(uumain(os::args())); } fn decode(input: &mut Reader, ignore_garbage: bool) { let mut to_decode = match input.read_to_str() { diff --git a/basename/basename.rs b/basename/basename.rs index e3c170ba1..6fdb51e54 100644 --- a/basename/basename.rs +++ b/basename/basename.rs @@ -24,9 +24,9 @@ static NAME: &'static str = "basename"; static VERSION: &'static str = "1.0.0"; #[allow(dead_code)] -fn main() { uumain(os::args()); } +fn main() { os::set_exit_status(uumain(os::args())); } -pub fn uumain(args: Vec) { +pub fn uumain(args: Vec) -> int { let program = strip_dir(args.get(0).as_slice()); // @@ -50,25 +50,25 @@ pub fn uumain(args: Vec) { print(getopts::usage("", opts).as_slice()); - return; + return 0; } if matches.opt_present("version") { println!("{} {}", program, VERSION); - return; + return 0; } // too few arguments if args.len() < 2 { println!("{}: {}", program, "missing operand"); println!("Try '{} --help' for more information.", program); - return; + return 0; } // too many arguments else if args.len() > 3 { println!("{}: extra operand '{}'", program, args.get(3)); println!("Try '{} --help' for more information.", program); - return; + return 0; } // @@ -85,6 +85,8 @@ pub fn uumain(args: Vec) { } println(name.as_slice()); + + 0 } fn strip_dir(fullname: &str) -> String { @@ -97,7 +99,7 @@ fn strip_dir(fullname: &str) -> String { name.push_char(c); } - return name.as_slice().chars().rev().collect(); + name.as_slice().chars().rev().collect() } fn strip_suffix(name: &str, suffix: &str) -> String { @@ -109,5 +111,5 @@ fn strip_suffix(name: &str, suffix: &str) -> String { return name.slice_to(name.len() - suffix.len()).into_string(); } - return name.into_string(); + name.into_string() } diff --git a/cat/cat.rs b/cat/cat.rs index 557a9feef..79caf0960 100644 --- a/cat/cat.rs +++ b/cat/cat.rs @@ -20,9 +20,9 @@ use std::io::{IoResult}; use std::ptr::{copy_nonoverlapping_memory}; #[allow(dead_code)] -fn main() { uumain(os::args()); } +fn main() { os::set_exit_status(uumain(os::args())); } -pub fn uumain(args: Vec) { +pub fn uumain(args: Vec) -> int { let program = args.get(0).as_slice(); let opts = [ getopts::optflag("A", "show-all", "equivalent to -vET"), @@ -53,11 +53,11 @@ pub fn uumain(args: Vec) { standard output.", opts).as_slice()); println!(""); println!("With no FILE, or when FILE is -, read standard input."); - return; + return 0; } if matches.opt_present("version") { println!("cat 1.0.0"); - return; + return 0; } let mut number_mode = NumberNone; @@ -80,6 +80,8 @@ pub fn uumain(args: Vec) { } exec(files, number_mode, show_nonprint, show_ends, show_tabs, squeeze_blank); + + 0 } #[deriving(Eq, PartialEq)] @@ -283,12 +285,12 @@ fn open(path: &str) -> Option<(Box, bool)> { } match File::open(&std::path::Path::new(path)) { - Ok(f) => return Some((box f as Box, false)), + Ok(f) => Some((box f as Box, false)), Err(e) => { (writeln!(stderr(), "cat: {0:s}: {1:s}", path, e.to_str())).unwrap(); - return None; + None }, - }; + } } struct UnsafeWriter<'a, W> { diff --git a/cksum/cksum.rs b/cksum/cksum.rs index 6907a2e40..8d1d5cba0 100644 --- a/cksum/cksum.rs +++ b/cksum/cksum.rs @@ -78,9 +78,9 @@ fn open_file(name: &str) -> IoResult> { } #[allow(dead_code)] -fn main() { uumain(os::args()); } +fn main() { os::set_exit_status(uumain(os::args())); } -pub fn uumain(args: Vec) { +pub fn uumain(args: Vec) -> int { let opts = [ getopts::optflag("h", "help", "display this help and exit"), getopts::optflag("V", "version", "output version information and exit"), @@ -98,12 +98,12 @@ pub fn uumain(args: Vec) { println!(" {} [OPTIONS] [FILE]...", NAME); println!(""); print(getopts::usage("Print CRC and size for each file.", opts.as_slice()).as_slice()); - return; + return 0; } if matches.opt_present("version") { println!("{} {}", NAME, VERSION); - return; + return 0; } let files = matches.free; @@ -111,15 +111,24 @@ pub fn uumain(args: Vec) { if files.is_empty() { match cksum("-") { Ok((crc, size)) => println!("{} {}", crc, size), - Err(err) => show_error!(2, "{}", err), + Err(err) => { + show_error!("{}", err); + return 2; + } } - return + return 0; } + let mut exit_code = 0; 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_error!("'{}' {}", fname, err); + exit_code = 2; + } } } + + exit_code } diff --git a/comm/comm.rs b/comm/comm.rs index 1cc1d2eeb..df5137516 100644 --- a/comm/comm.rs +++ b/comm/comm.rs @@ -95,9 +95,9 @@ fn open_file(name: &str) -> IoResult> { } #[allow(dead_code)] -fn main() { uumain(os::args()); } +fn main() { os::set_exit_status(uumain(os::args())); } -pub fn uumain(args: Vec) { +pub fn uumain(args: Vec) -> int { let opts = [ getopts::optflag("1", "", "suppress column 1 (lines uniq to FILE1)"), getopts::optflag("2", "", "suppress column 2 (lines uniq to FILE2)"), @@ -114,7 +114,7 @@ pub fn uumain(args: Vec) { if matches.opt_present("version") { println!("{} {}", NAME, VERSION); - return; + return 0; } if matches.opt_present("help") || matches.free.len() != 2 { @@ -125,14 +125,16 @@ pub fn uumain(args: Vec) { println!(""); print(getopts::usage("Compare sorted files line by line.", opts.as_slice()).as_slice()); if matches.free.len() != 2 { - os::set_exit_status(1); + return 0; } - return; + return 0; } let mut f1 = open_file(matches.free.get(0).as_slice()).unwrap(); let mut f2 = open_file(matches.free.get(1).as_slice()).unwrap(); - comm(&mut f1, &mut f2, &matches) + comm(&mut f1, &mut f2, &matches); + + 0 } diff --git a/common/util.rs b/common/util.rs index 14ae5d70d..d5e65c7f6 100644 --- a/common/util.rs +++ b/common/util.rs @@ -13,8 +13,7 @@ extern crate libc; #[macro_export] macro_rules! show_error( - ($exitcode:expr, $($args:expr),+) => ({ - ::std::os::set_exit_status($exitcode as int); + ($($args:expr),+) => ({ safe_write!(&mut ::std::io::stderr(), "{}: error: ", ::NAME); safe_writeln!(&mut ::std::io::stderr(), $($args),+); }) @@ -31,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/cp/cp.rs b/cp/cp.rs index 7176d9007..66e7ec79a 100644 --- a/cp/cp.rs +++ b/cp/cp.rs @@ -12,7 +12,7 @@ */ extern crate getopts; -#[phase(syntax, link)] extern crate log; +#[phase(plugin, link)] extern crate log; use std::os; use std::io; @@ -32,9 +32,9 @@ pub enum Mode { } #[allow(dead_code)] -fn main() { uumain(os::args()); } +fn main() { os::set_exit_status(uumain(os::args())); } -pub fn uumain(args: Vec) { +pub fn uumain(args: Vec) -> int { let opts = [ optflag("h", "help", "display this help and exit"), optflag("", "version", "output version information and exit"), @@ -62,6 +62,8 @@ pub fn uumain(args: Vec) { Help => help(progname.as_slice(), usage.as_slice()), Version => version(), } + + 0 } fn version() { diff --git a/dirname/dirname.rs b/dirname/dirname.rs index 196d7bef4..3e6714f23 100644 --- a/dirname/dirname.rs +++ b/dirname/dirname.rs @@ -17,9 +17,9 @@ use std::io::print; static VERSION: &'static str = "1.0.0"; #[allow(dead_code)] -fn main() { uumain(os::args()); } +fn main() { os::set_exit_status(uumain(os::args())); } -pub fn uumain(args: Vec) { +pub fn uumain(args: Vec) -> int { let program = args.get(0).clone(); let opts = [ getopts::optflag("z", "zero", "separate output with NUL rather than newline"), @@ -41,11 +41,12 @@ pub fn uumain(args: Vec) { print(getopts::usage("Output each NAME with its last non-slash component and trailing slashes removed; if NAME contains no /'s, output '.' (meaning the current directory).", opts).as_slice()); - return; + return 0; } if matches.opt_present("version") { - return println!("dirname version: {:s}", VERSION); + println!("dirname version: {:s}", VERSION); + return 0; } let separator = match matches.opt_present("zero") { @@ -66,4 +67,6 @@ directory).", opts).as_slice()); println!("{0:s}: missing operand", program); println!("Try '{0:s} --help' for more information.", program); } + + 0 } diff --git a/du/du.rs b/du/du.rs index 055e1d211..36abca4df 100644 --- a/du/du.rs +++ b/du/du.rs @@ -14,15 +14,14 @@ extern crate getopts; extern crate libc; -extern crate sync; extern crate time; use std::os; use std::io::{stderr, fs, FileStat, TypeDirectory}; use std::option::Option; use std::path::Path; +use std::sync::{Arc, Future}; use time::Timespec; -use sync::{Arc, Future}; #[path = "../common/util.rs"] mod util; @@ -87,13 +86,13 @@ fn du(path: &Path, mut my_stat: Stat, stats.push(Arc::new(my_stat)); - return stats; + stats } #[allow(dead_code)] -fn main() { uumain(os::args()); } +fn main() { os::set_exit_status(uumain(os::args())); } -pub fn uumain(args: Vec) { +pub fn uumain(args: Vec) -> int { let program = args.get(0).as_slice(); let opts = [ // In task @@ -163,8 +162,8 @@ pub fn uumain(args: Vec) { let matches = match getopts::getopts(args.tail(), opts) { Ok(m) => m, Err(f) => { - show_error!(1, "Invalid options\n{}", f.to_err_msg()); - return + show_error!("Invalid options\n{}", f.to_err_msg()); + return 1; } }; @@ -188,10 +187,10 @@ ers of 1000).", program = program, version = VERSION, usage = getopts::usage("Summarize disk usage of each FILE, recursively for directories.", opts)); - return + return 0; } else if matches.opt_present("version") { println!("{} version: {}", program, VERSION); - return + return 0; } let summarize = matches.opt_present("summarize"); @@ -201,11 +200,11 @@ ers of 1000).", match (max_depth_str, max_depth) { (Some(ref s), _) if summarize => { println!("{}: warning: summarizing conflicts with --max-depth={:s}", program, *s); - return + return 0; } (Some(ref s), None) => { println!("{}: invalid maximum depth '{:s}'", program, *s); - return + return 0; } (Some(_), Some(_)) | (None, _) => { /* valid */ } } @@ -240,7 +239,7 @@ ers of 1000).", for c in s.as_slice().chars() { if found_letter && c.is_digit() || !found_number && !c.is_digit() { println!("{}: invalid --block-size argument '{}'", program, s); - return + return 0; } else if c.is_digit() { found_number = true; numbers.push(c as u8); @@ -262,7 +261,7 @@ ers of 1000).", "ZB" => 1000 * 1000 * 1000 * 1000 * 1000 * 1000 * 1000, "YB" => 1000 * 1000 * 1000 * 1000 * 1000 * 1000 * 1000 * 1000, _ => { - println!("{}: invalid --block-size argument '{}'", program, s); return + println!("{}: invalid --block-size argument '{}'", program, s); return 0; } }; number * multiple @@ -301,7 +300,7 @@ Valid arguments are: - 'long-iso' - 'iso' Try '{program} --help' for more information.", s, program = program); - return + return 0; } } }, @@ -340,7 +339,7 @@ Try '{program} --help' for more information.", s, program = program); Valid arguments are: - 'accessed', 'created', 'modified' Try '{program} --help' for more information.", program = program); - return + return 0; } }, None => stat.fstat.modified @@ -367,4 +366,6 @@ Try '{program} --help' for more information.", s, program = program); print!("{:<10} total", convert_size(grand_total)); print!("{}", line_separator); } + + 0 } diff --git a/echo/echo.rs b/echo/echo.rs index 75e798593..f8edf5175 100644 --- a/echo/echo.rs +++ b/echo/echo.rs @@ -66,13 +66,14 @@ fn convert_str(string: &str, index: uint, base: uint) -> (char, int) { } } } - return (to_char(&bytes, base), max_digits) + + (to_char(&bytes, base), max_digits) } #[allow(dead_code)] -fn main() { uumain(os::args()); } +fn main() { os::set_exit_status(uumain(os::args())); } -pub fn uumain(args: Vec) { +pub fn uumain(args: Vec) -> int { let program = args.get(0).clone(); let opts = [ getopts::optflag("n", "", "do not output the trailing newline"), @@ -109,11 +110,12 @@ pub fn uumain(args: Vec) { \\v vertical tab \\0NNN byte with octal value NNN (1 to 3 digits) \\xHH byte with hexadecimal value HH (1 to 2 digits)"); - return; + return 0; } if matches.opt_present("version") { - return println!("echo version: {:s}", VERSION); + println!("echo version: {:s}", VERSION); + return 0; } if !matches.free.is_empty() { @@ -185,4 +187,6 @@ pub fn uumain(args: Vec) { if !matches.opt_present("n") { println!("") } + + 0 } diff --git a/env/env.rs b/env/env.rs index b3d365af5..f2434974d 100644 --- a/env/env.rs +++ b/env/env.rs @@ -54,9 +54,9 @@ fn print_env(null: bool) { } #[allow(dead_code)] -fn main() { uumain(os::args()); } +fn main() { os::set_exit_status(uumain(os::args())); } -pub fn uumain(args: Vec) { +pub fn uumain(args: Vec) -> int { let prog = args.get(0).as_slice(); // to handle arguments the same way than GNU env, we can't use getopts @@ -97,8 +97,8 @@ pub fn uumain(args: Vec) { } } else if opt.as_slice().starts_with("--") { match opt.as_slice() { - "--help" => { usage(prog); return } - "--version" => { version(); return } + "--help" => { usage(prog); return 0; } + "--version" => { version(); return 0; } "--ignore-environment" => opts.ignore_env = true, "--null" => opts.null = true, @@ -114,7 +114,7 @@ pub fn uumain(args: Vec) { _ => { println!("{:s}: invalid option \"{:s}\"", prog, *opt); println!("Type \"{:s} --help\" for detailed informations", prog); - return + return 0; } } } else if opt.as_slice().starts_with("-") { @@ -131,8 +131,8 @@ pub fn uumain(args: Vec) { for c in chars { // short versions of options match c { - 'h' => { usage(prog); return } - 'V' => { version(); return } + 'h' => { usage(prog); return 0; } + 'V' => { version(); return 0; } 'i' => opts.ignore_env = true, '0' => opts.null = true, 'u' => { @@ -146,7 +146,7 @@ pub fn uumain(args: Vec) { _ => { println!("{:s}: illegal option -- {:c}", prog, c); println!("Type \"{:s} --help\" for detailed informations", prog); - return + return 0; } } } @@ -200,14 +200,16 @@ pub fn uumain(args: Vec) { let args = opts.program.slice_from(1); match Command::new(prog).args(args).stdin(InheritFd(0)).stdout(InheritFd(1)).stderr(InheritFd(2)).status() { Ok(exit) => - std::os::set_exit_status(match exit { + return match exit { std::io::process::ExitStatus(s) => s, _ => 1 - }), - Err(_) => std::os::set_exit_status(1) + }, + Err(_) => return 1 } } else { // no program provided print_env(opts.null); } + + 0 } diff --git a/fold/fold.rs b/fold/fold.rs index e5ccc732b..711bc879e 100644 --- a/fold/fold.rs +++ b/fold/fold.rs @@ -27,9 +27,9 @@ static NAME: &'static str = "fold"; static VERSION: &'static str = "1.0.0"; #[allow(dead_code)] -fn main() { uumain(os::args()); } +fn main() { os::set_exit_status(uumain(os::args())); } -pub fn uumain(args: Vec) { +pub fn uumain(args: Vec) -> int { let (args, obs_width) = handle_obsolete(args.as_slice()); let program = args.get(0).clone(); @@ -82,6 +82,8 @@ pub fn uumain(args: Vec) { }; fold(files, bytes, spaces, width); } + + 0 } fn handle_obsolete(args: &[String]) -> (Vec, Option) { diff --git a/groups/groups.rs b/groups/groups.rs index d344e9583..abb770972 100644 --- a/groups/groups.rs +++ b/groups/groups.rs @@ -26,9 +26,9 @@ use c_types::{get_pw_from_args, group}; static NAME: &'static str = "groups"; #[allow(dead_code)] -fn main () { uumain(os::args()); } +fn main () { os::set_exit_status(uumain(os::args())); } -pub fn uumain(args: Vec) { +pub fn uumain(args: Vec) -> int { let options = [ optflag("h", "", "Help") ]; @@ -36,10 +36,12 @@ pub fn uumain(args: Vec) { let matches = match getopts(args.tail(), options) { Ok(m) => { m }, Err(_) => { - show_error!(1, "{}", usage(NAME, options)); - return; + show_error!("{}", usage(NAME, options)); + return 1; } }; group(get_pw_from_args(&matches.free), true); + + 0 } diff --git a/head/head.rs b/head/head.rs index 70fe114df..37adad266 100644 --- a/head/head.rs +++ b/head/head.rs @@ -23,9 +23,9 @@ use getopts::{optopt, optflag, getopts, usage}; static PROGRAM: &'static str = "head"; #[allow(dead_code)] -fn main () { uumain(os::args()); } +fn main () { os::set_exit_status(uumain(os::args())); } -pub fn uumain(args: Vec) { +pub fn uumain(args: Vec) -> int { let mut line_count = 10u; // handle obsolete -number syntax @@ -46,15 +46,15 @@ pub fn uumain(args: Vec) { Ok (m) => { m } Err(_) => { println!("{:s}", usage(PROGRAM, possible_options)); - return + return 0; } }; if given_options.opt_present("h") { println!("{:s}", usage(PROGRAM, possible_options)); - return; + return 0; } - if given_options.opt_present("V") { version(); return } + if given_options.opt_present("V") { version(); return 0 } match given_options.opt_str("n") { Some(n) => { @@ -93,6 +93,8 @@ pub fn uumain(args: Vec) { head(&mut buffer, line_count); } } + + 0 } // It searches for an option in the form of -123123 diff --git a/hostid/hostid.rs b/hostid/hostid.rs index 6ce2d77e0..f1fa4ce72 100644 --- a/hostid/hostid.rs +++ b/hostid/hostid.rs @@ -18,7 +18,7 @@ extern crate serialize; extern crate libc; -#[phase(syntax, link)] extern crate log; +#[phase(plugin, link)] extern crate log; use std::os; @@ -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, @@ -50,9 +50,9 @@ extern { } #[allow(dead_code)] -fn main() { uumain(os::args()); } +fn main() { os::set_exit_status(uumain(os::args())); } -pub fn uumain(args: Vec) { +pub fn uumain(args: Vec) -> int { let opts = [ optflag("", "help", "display this help and exit"), @@ -65,8 +65,8 @@ pub fn uumain(args: Vec) { 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 + show_error!("{}\n{}", e.to_err_msg(), get_help_text(NAME, usage.as_slice())); + return EXIT_ERR; }, }; @@ -83,6 +83,8 @@ pub fn uumain(args: Vec) { Help => help(NAME, usage.as_slice()), Version => version(), } + + 0 } fn version() { diff --git a/hostname/hostname.rs b/hostname/hostname.rs index f78dd1173..ed4f30930 100644 --- a/hostname/hostname.rs +++ b/hostname/hostname.rs @@ -24,9 +24,9 @@ extern { } #[allow(dead_code)] -fn main () { uumain(os::args()); } +fn main () { os::set_exit_status(uumain(os::args())); } -pub fn uumain(args: Vec) { +pub fn uumain(args: Vec) -> int { let program = args.get(0); let options = [ @@ -38,14 +38,14 @@ pub fn uumain(args: Vec) { let matches = match getopts(args.tail(), options) { Ok(m) => { m } - _ => { help_menu(program.as_slice(), options); return; } + _ => { help_menu(program.as_slice(), options); return 0; } }; if matches.opt_present("h") { help_menu(program.as_slice(), options); - return + return 0 } - if matches.opt_present("V") { version(); return } + if matches.opt_present("V") { version(); return 0 } match matches.free.len() { 0 => { @@ -55,7 +55,7 @@ pub fn uumain(args: Vec) { let pos = hostname.as_slice().find_str("."); if pos.is_some() { println!("{:s}", hostname.as_slice().slice_to(pos.unwrap())); - return; + return 0; } } @@ -64,6 +64,8 @@ pub fn uumain(args: Vec) { 1 => { xsethostname( matches.free.last().unwrap().as_slice() ) } _ => { help_menu(program.as_slice(), options); } }; + + 0 } fn version() { diff --git a/id/id.rs b/id/id.rs index cd3c4364d..6952b8d2d 100644 --- a/id/id.rs +++ b/id/id.rs @@ -88,9 +88,9 @@ extern { static NAME: &'static str = "id"; #[allow(dead_code)] -fn main () { uumain(os::args()); } +fn main () { os::set_exit_status(uumain(os::args())); } -pub fn uumain(args: Vec) { +pub fn uumain(args: Vec) -> int { let args_t = args.tail(); let options = [ @@ -109,18 +109,18 @@ pub fn uumain(args: Vec) { Ok(m) => { m }, Err(_) => { println!("{:s}", usage(NAME, options)); - return; + return 0; } }; if matches.opt_present("h") { println!("{:s}", usage(NAME, options)); - return; + return 0; } if matches.opt_present("A") { auditid(); - return; + return 0; } @@ -149,7 +149,7 @@ pub fn uumain(args: Vec) { } else { println!("{:u}", id); } - return; + return 0; } if uflag { @@ -171,22 +171,22 @@ pub fn uumain(args: Vec) { println!("{:d}", id); } - return; + return 0; } if matches.opt_present("G") { group(possible_pw, nflag); - return; + return 0; } if matches.opt_present("P") { pline(possible_pw); - return; + return 0; }; if matches.opt_present("p") { pretty(possible_pw); - return; + return 0; } if possible_pw.is_some() { @@ -194,6 +194,8 @@ pub fn uumain(args: Vec) { } else { id_print(possible_pw, false, true, true) } + + 0 } fn pretty(possible_pw: Option) { diff --git a/kill/kill.rs b/kill/kill.rs index f2dbe8b3e..0aa33fd75 100644 --- a/kill/kill.rs +++ b/kill/kill.rs @@ -17,7 +17,7 @@ extern crate libc; extern crate collections; extern crate serialize; -#[phase(syntax, link)] extern crate log; +#[phase(plugin, link)] extern crate log; use std::os; use std::from_str::from_str; @@ -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, @@ -53,9 +53,9 @@ pub enum Mode { } #[allow(dead_code)] -fn main() { uumain(os::args()); } +fn main() { os::set_exit_status(uumain(os::args())); } -pub fn uumain(args: Vec) { +pub fn uumain(args: Vec) -> int { let opts = [ optflag("h", "help", "display this help and exit"), @@ -71,8 +71,8 @@ pub fn uumain(args: Vec) { 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 + show_error!("{}\n{}", e.to_err_msg(), get_help_text(NAME, usage.as_slice())); + return EXIT_ERR; }, }; @@ -96,6 +96,8 @@ pub fn uumain(args: Vec) { Help => help(NAME, usage.as_slice()), Version => version(), } + + 0 } fn version() { @@ -126,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) @@ -175,7 +177,7 @@ fn signal_by_name_or_value(signal_name_or_value: &str) -> Option { return Some(signal.value); } } - return None; + None } fn kill(signalname: &str, pids: std::vec::Vec) { diff --git a/logname/logname.rs b/logname/logname.rs index 1e6ea6650..d28dca8f0 100644 --- a/logname/logname.rs +++ b/logname/logname.rs @@ -44,9 +44,9 @@ fn version() { } #[allow(dead_code)] -fn main() { uumain(os::args()); } +fn main() { os::set_exit_status(uumain(os::args())); } -pub fn uumain(args: Vec) { +pub fn uumain(args: Vec) -> int { let program = args.get(0).clone(); // @@ -69,14 +69,16 @@ pub fn uumain(args: Vec) { println!(" {:s}", program); println!(""); print(getopts::usage("print user's login name", opts).as_slice()); - return; + return 0; } if matches.opt_present("version") { version(); - return; + return 0; } exec(); + + 0 } fn exec() { diff --git a/md5sum/md5sum.rs b/md5sum/md5sum.rs index b368e302a..da4133573 100644 --- a/md5sum/md5sum.rs +++ b/md5sum/md5sum.rs @@ -27,8 +27,10 @@ mod util; static NAME: &'static str = "md5sum"; static VERSION: &'static str = "1.0.0"; -fn main() { - let args = os::args(); +#[allow(dead_code)] +fn main() { os::set_exit_status(uumain(os::args())); } + +pub fn uumain(args: Vec) -> int { let program = args.get(0).clone(); @@ -72,11 +74,16 @@ fn main() { } else { matches.free }; - md5sum(files, binary, check, tag, status, quiet, strict, warn); + match md5sum(files, binary, check, tag, status, quiet, strict, warn) { + Ok(()) => return 0, + Err(e) => return e + } } + + 0 } -fn md5sum(files: Vec, binary: bool, check: bool, tag: bool, status: bool, quiet: bool, strict: bool, warn: bool) { +fn md5sum(files: Vec, binary: bool, check: bool, tag: bool, status: bool, quiet: bool, strict: bool, warn: bool) -> Result<(), int> { let mut md5 = crypto::md5::Md5::new(); let bytes = md5.output_bits() / 4; let mut bad_format = 0; @@ -102,7 +109,7 @@ fn md5sum(files: Vec, binary: bool, check: bool, tag: bool, status: bool None => { bad_format += 1; if strict { - os::set_exit_status(1); + return Err(1); } if warn { show_warning!("{}: {}: improperly formatted MD5 checksum line", filename, i + 1); @@ -121,7 +128,6 @@ fn md5sum(files: Vec, binary: bool, check: bool, tag: bool, status: bool println!("{}: FAILED", ck_filename); } failed += 1; - os::set_exit_status(1); } } } else { @@ -143,6 +149,8 @@ fn md5sum(files: Vec, binary: bool, check: bool, tag: bool, status: bool show_warning!("{} computed checksum did NOT match", failed); } } + + Ok(()) } fn calc_sum(md5: &mut crypto::md5::Md5, file: &mut Reader, binary: bool) -> String { diff --git a/mkdir/mkdir.rs b/mkdir/mkdir.rs index eb88c1942..7dadfa0ce 100644 --- a/mkdir/mkdir.rs +++ b/mkdir/mkdir.rs @@ -29,9 +29,9 @@ static VERSION: &'static str = "1.0.0"; * Handles option parsing */ #[allow(dead_code)] -fn main() { uumain(os::args()); } +fn main() { os::set_exit_status(uumain(os::args())); } -pub fn uumain(args: Vec) { +pub fn uumain(args: Vec) -> int { let opts = [ // Linux-specific options, not implemented @@ -54,11 +54,11 @@ pub fn uumain(args: Vec) { if args.len() == 1 || matches.opt_present("help") { print_help(opts); - return; + return 0; } if matches.opt_present("version") { println!("mkdir v{}", VERSION); - return; + return 0; } let verbose_flag = matches.opt_present("verbose"); let mk_parents = matches.opt_present("parents"); @@ -84,7 +84,10 @@ pub fn uumain(args: Vec) { if dirs.is_empty() { crash!(1, "missing operand"); } - exec(dirs, mk_parents, mode, verbose_flag); + match exec(dirs, mk_parents, mode, verbose_flag) { + Ok(()) => 0, + Err(e) => e + } } fn print_help(opts: &[getopts::OptGroup]) { @@ -97,7 +100,9 @@ fn print_help(opts: &[getopts::OptGroup]) { /** * Create the list of new directories */ -fn exec(dirs: Vec, mk_parents: bool, mode: FilePermission, verbose: bool) { +fn exec(dirs: Vec, mk_parents: bool, mode: FilePermission, verbose: bool) -> Result<(), int> { + let mut result = Ok(()); + let mut parent_dirs = Vec::new(); if mk_parents { for dir in dirs.iter() { @@ -116,7 +121,10 @@ fn exec(dirs: Vec, mk_parents: bool, mode: FilePermission, verbose: bool } // Recursively build parent dirs that are needed if !parent_dirs.is_empty() { - exec(parent_dirs, mk_parents, mode, verbose); + match exec(parent_dirs, mk_parents, mode, verbose) { + Ok(()) => ( /* keep going */ ), + Err(e) => result = Err(e) + } } for dir in dirs.iter() { @@ -138,9 +146,12 @@ fn exec(dirs: Vec, mk_parents: bool, mode: FilePermission, verbose: bool } else { format!("directory '{}' already exists", *dir) }; - show_error!(1, "{}", error_msg); + show_error!("{}", error_msg); + result = Err(1) } } + + result } /** diff --git a/paste/paste.rs b/paste/paste.rs index 31b55d681..1cc5c3c42 100644 --- a/paste/paste.rs +++ b/paste/paste.rs @@ -24,9 +24,9 @@ static NAME: &'static str = "paste"; static VERSION: &'static str = "1.0.0"; #[allow(dead_code)] -fn main() { uumain(os::args()); } +fn main() { os::set_exit_status(uumain(os::args())); } -pub fn uumain(args: Vec) { +pub fn uumain(args: Vec) -> int { let program = args.get(0).clone(); let opts = [ @@ -56,6 +56,8 @@ pub fn uumain(args: Vec) { }; paste(matches.free, serial, delimiters.as_slice()); } + + 0 } fn paste(filenames: Vec, serial: bool, delimiters: &str) { diff --git a/printenv/printenv.rs b/printenv/printenv.rs index 1df80e271..8eb9cde19 100644 --- a/printenv/printenv.rs +++ b/printenv/printenv.rs @@ -25,9 +25,9 @@ mod util; static NAME: &'static str = "printenv"; #[allow(dead_code)] -fn main() { uumain(os::args()); } +fn main() { os::set_exit_status(uumain(os::args())); } -pub fn uumain(args: Vec) { +pub fn uumain(args: Vec) -> int { let program = args.get(0).clone(); let opts = [ getopts::optflag("0", "null", "end each output line with 0 byte rather than newline"), @@ -47,11 +47,11 @@ pub fn uumain(args: Vec) { println!(" {0:s} [VARIABLE]... [OPTION]...", program); println!(""); print(getopts::usage("Prints the given environment VARIABLE(s), otherwise prints them all.", opts).as_slice()); - return; + return 0; } if matches.opt_present("version") { println!("printenv 1.0.0"); - return; + return 0; } let mut separator = "\n"; if matches.opt_present("null") { @@ -59,6 +59,8 @@ pub fn uumain(args: Vec) { }; exec(matches.free, separator); + + 0 } pub fn exec(args: Vec, separator: &str) { diff --git a/pwd/pwd.rs b/pwd/pwd.rs index e8831237c..7283179c7 100644 --- a/pwd/pwd.rs +++ b/pwd/pwd.rs @@ -24,9 +24,9 @@ static NAME: &'static str = "pwd"; static VERSION: &'static str = "1.0.0"; #[allow(dead_code)] -fn main() { uumain(os::args()); } +fn main() { os::set_exit_status(uumain(os::args())); } -pub fn uumain(args: Vec) { +pub fn uumain(args: Vec) -> int { let program = args.get(0).clone(); let opts = [ getopts::optflag("", "help", "display this help and exit"), @@ -48,9 +48,15 @@ pub fn uumain(args: Vec) { println!(""); print(getopts::usage("Print the full filename of the current working directory.", opts).as_slice()); } else if matches.opt_present("version") { - return println!("pwd version: {}", VERSION); + println!("pwd version: {}", VERSION); + + return 0; } else { let cwd = std::os::getcwd(); println!("{}", cwd.display()); + + return 0; } + + 0 } diff --git a/rm/rm.rs b/rm/rm.rs index 057013c1b..f0372391e 100644 --- a/rm/rm.rs +++ b/rm/rm.rs @@ -30,9 +30,9 @@ enum InteractiveMode { static NAME: &'static str = "rm"; #[allow(dead_code)] -fn main() { uumain(os::args()); } +fn main() { os::set_exit_status(uumain(os::args())); } -pub fn uumain(args: Vec) { +pub fn uumain(args: Vec) -> int { let program = args.get(0).clone(); // TODO: make getopts support -R in addition to -r @@ -79,8 +79,9 @@ pub fn uumain(args: Vec) { } 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_error!("missing an argument"); + show_error!("for help, try '{0:s} --help'", program); + return 1; } else { let force = matches.opt_present("force"); let interactive = @@ -113,16 +114,23 @@ pub fn uumain(args: Vec) { "Remove all arguments? " }; if !prompt(msg) { - return; + 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 + } } + + 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> { + let mut r = Ok(()); + for filename in files.iter() { let filename = filename.as_slice(); let file = Path::new(filename); @@ -135,30 +143,34 @@ 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); + r = remove(walk_dir.map(|x| x.as_str().unwrap().to_string()).collect(), force, interactive, one_fs, preserve_root, recursive, dir, verbose).and(r); + r = remove_dir(&file, filename, interactive, verbose).and(r); } else if dir && (filename != "/" || !preserve_root) { - remove_dir(&file, filename, interactive, verbose); + r = remove_dir(&file, filename, interactive, verbose).and(r); } else { if recursive { - show_error!(1, "could not remove directory '{}'", + show_error!("could not remove directory '{}'", filename); + r = Err(1); } else { - show_error!(1, - "could not remove directory '{}' (did you mean to pass '-r'?)", + show_error!("could not remove directory '{}' (did you mean to pass '-r'?)", filename); + r = Err(1); } } } else { - remove_file(&file, filename.as_slice(), interactive, verbose); + r = remove_file(&file, filename.as_slice(), interactive, verbose).and(r); } } else if !force { - show_error!(1, "no such file or directory '{}'", filename); + show_error!("no such file or directory '{}'", filename); + r = Err(1); } } + + r } -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) @@ -169,13 +181,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_error!("{}", f.to_str()); + return Err(1); } } } + + 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) @@ -186,10 +201,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_error!("{}", f.to_str()); + return Err(1); } } } + + Ok(()) } fn prompt_file(path: &Path, name: &str) -> bool { diff --git a/rmdir/rmdir.rs b/rmdir/rmdir.rs index 14052754c..d2dcba897 100644 --- a/rmdir/rmdir.rs +++ b/rmdir/rmdir.rs @@ -23,9 +23,9 @@ mod util; static NAME: &'static str = "rmdir"; #[allow(dead_code)] -fn main() { uumain(os::args()); } +fn main() { os::set_exit_status(uumain(os::args())); } -pub fn uumain(args: Vec) { +pub fn uumain(args: Vec) -> int { let program = args.get(0).clone(); let opts = [ @@ -38,8 +38,8 @@ pub fn uumain(args: Vec) { let matches = match getopts::getopts(args.tail(), opts) { Ok(m) => m, Err(f) => { - show_error!(1, "{}", f.to_err_msg()); - return; + show_error!("{}", f.to_err_msg()); + return 1; } }; @@ -53,39 +53,54 @@ pub fn uumain(args: Vec) { } 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_error!("missing an argument"); + show_error!("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 + } } + + 0 } -fn remove(dirs: Vec, ignore: bool, parents: bool, verbose: bool) { +fn remove(dirs: Vec, ignore: bool, parents: bool, verbose: bool) -> Result<(), int>{ + let mut r = Ok(()); + 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); + r = remove_dir(&path, dir.as_slice(), ignore, parents, verbose).and(r); } else { - show_error!(1, "failed to remove '{}' (file)", *dir); + show_error!("failed to remove '{}' (file)", *dir); + r = Err(1); } } else { - show_error!(1, "no such file or directory '{}'", *dir); + show_error!("no such file or directory '{}'", *dir); + r = Err(1); } } + + r } -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_error!("{}", f.to_str()); + return Err(1); } }; + + let mut r = Ok(()); + if walk_dir.next() == None { match fs::rmdir(path) { Ok(_) => { @@ -95,16 +110,20 @@ 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); + r = remove_dir(&Path::new(dirname), dirname, ignore, parents, verbose).and(r); } } } Err(f) => { - show_error!(1, "{}", f.to_str()); + show_error!("{}", f.to_str()); + r = Err(1); } } } else if !ignore { - show_error!(1, "Failed to remove directory '{}' (non-empty)", dir); + show_error!("Failed to remove directory '{}' (non-empty)", dir); + r = Err(1); } + + r } diff --git a/seq/seq.rs b/seq/seq.rs index c0c098763..392bef040 100644 --- a/seq/seq.rs +++ b/seq/seq.rs @@ -34,9 +34,9 @@ fn escape_sequences(s: &str) -> String { } #[allow(dead_code)] -fn main() { uumain(os::args()); } +fn main() { os::set_exit_status(uumain(os::args())); } -pub fn uumain(args: Vec) { +pub fn uumain(args: Vec) -> int { let opts = [ getopts::optopt("s", "separator", "Separator character (defaults to \\n)", ""), getopts::optopt("t", "terminator", "Terminator character (defaults to separator)", ""), @@ -47,28 +47,27 @@ pub fn uumain(args: Vec) { let matches = match getopts::getopts(args.tail(), opts) { Ok(m) => { m } Err(f) => { - show_error!(1, "{:s}", f.to_err_msg()); + show_error!("{:s}", f.to_err_msg()); print_usage(opts); - return; + return 1; } }; if matches.opt_present("help") { print_usage(opts); - return; + return 0; } if matches.opt_present("version") { println!("seq 1.0.0"); - return; + return 0; } if matches.free.len() < 1 || matches.free.len() > 3 { - os::set_exit_status(1); print_usage(opts); - return; + return 1; } 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; } + Err(s) => { show_error!("{:s}", s); return 1; } } } else { 1.0 @@ -76,18 +75,20 @@ pub fn uumain(args: Vec) { 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; } + Err(s) => { show_error!("{: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; } + Err(s) => { show_error!("{: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()); print_seq(first, step, last, separator, terminator, matches.opt_present("w")); + + 0 } fn done_printing(next: f32, step: f32, last: f32) -> bool { diff --git a/sleep/sleep.rs b/sleep/sleep.rs index fe020fa8f..5f07ac40f 100644 --- a/sleep/sleep.rs +++ b/sleep/sleep.rs @@ -24,9 +24,9 @@ mod util; static NAME: &'static str = "sleep"; #[allow(dead_code)] -fn main() { uumain(os::args()); } +fn main() { os::set_exit_status(uumain(os::args())); } -pub fn uumain(args: Vec) { +pub fn uumain(args: Vec) -> int { let program = args.get(0).clone(); let opts = [ @@ -36,8 +36,8 @@ pub fn uumain(args: Vec) { let matches = match getopts::getopts(args.tail(), opts) { Ok(m) => m, Err(f) => { - show_error!(1, "{}", f.to_err_msg()); - return + show_error!("{}", f.to_err_msg()); + return 1; } }; @@ -57,11 +57,14 @@ 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_error!("missing an argument"); + show_error!("for help, try '{0:s} --help'", program); + return 1; } else { sleep(matches.free); } + + 0 } fn sleep(args: Vec) { diff --git a/sum/sum.rs b/sum/sum.rs index 352f1cf44..177fe7590 100644 --- a/sum/sum.rs +++ b/sum/sum.rs @@ -77,9 +77,9 @@ fn open(name: &str) -> IoResult> { } #[allow(dead_code)] -fn main() { uumain(os::args()); } +fn main() { os::set_exit_status(uumain(os::args())); } -pub fn uumain(args: Vec) { +pub fn uumain(args: Vec) -> int { let program = args.get(0).as_slice(); let opts = [ getopts::optflag("r", "", "use the BSD compatible algorithm (default)"), @@ -102,11 +102,11 @@ pub fn uumain(args: Vec) { print(getopts::usage("checksum and count the blocks in a file", opts).as_slice()); println!(""); println!("With no FILE, or when FILE is -, read standard input."); - return; + return 0; } if matches.opt_present("version") { println!("{} {}", program, VERSION); - return; + return 0; } let sysv = matches.opt_present("sysv"); @@ -128,4 +128,6 @@ pub fn uumain(args: Vec) { }; println!("{} {}", sum, blocks); + + 0 } diff --git a/tac/tac.rs b/tac/tac.rs index 90307d040..30ddfeb20 100644 --- a/tac/tac.rs +++ b/tac/tac.rs @@ -24,9 +24,9 @@ static NAME: &'static str = "tac"; static VERSION: &'static str = "1.0.0"; #[allow(dead_code)] -fn main() { uumain(os::args()); } +fn main() { os::set_exit_status(uumain(os::args())); } -pub fn uumain(args: Vec) { +pub fn uumain(args: Vec) -> int { let program = args.get(0).clone(); let opts = [ @@ -69,6 +69,8 @@ pub fn uumain(args: Vec) { }; tac(files, before, regex, separator.as_slice()); } + + 0 } fn tac(filenames: Vec, before: bool, _: bool, separator: &str) { diff --git a/tee/tee.rs b/tee/tee.rs index b4af3a42c..83fc010e9 100644 --- a/tee/tee.rs +++ b/tee/tee.rs @@ -13,24 +13,24 @@ */ extern crate getopts; -#[phase(syntax, link)] extern crate log; +#[phase(plugin, link)] extern crate log; use std::io::{println, stdin, stdout, Append, File, Truncate, Write}; use std::io::{IoResult}; use std::io::util::{copy, NullWriter, MultiWriter}; -use std::os::{args, set_exit_status}; +use std::os; use getopts::{getopts, optflag, usage}; static NAME: &'static str = "tee"; static VERSION: &'static str = "1.0.0"; #[allow(dead_code)] -fn main() { uumain(args()); } +fn main() { os::set_exit_status(uumain(os::args())); } -pub fn uumain(args: Vec) { +pub fn uumain(args: Vec) -> int { match options(args.as_slice()).and_then(exec) { - Ok(_) => set_exit_status(0), - Err(_) => set_exit_status(1) + Ok(_) => 0, + Err(_) => 1 } } @@ -153,5 +153,5 @@ fn with_path(path: &Path, cb: || -> IoResult) -> IoResult { } fn warn(message: &str) { - error!("{}: {}", args().get(0), message); + error!("{}: {}", os::args().get(0), message); } diff --git a/touch/touch.rs b/touch/touch.rs index 0886e15a2..abe98a39f 100644 --- a/touch/touch.rs +++ b/touch/touch.rs @@ -23,9 +23,9 @@ static NAME: &'static str = "touch"; static VERSION: &'static str = "1.0.0"; #[allow(dead_code)] -fn main() { uumain(os::args()); } +fn main() { os::set_exit_status(uumain(os::args())); } -pub fn uumain(args: Vec) { +pub fn uumain(args: Vec) -> int { let opts = [ getopts::optflag("a", "", "change only the access time"), getopts::optflag("c", "no-create", "do not create any files"), @@ -49,7 +49,7 @@ pub fn uumain(args: Vec) { if matches.opt_present("version") { println!("{:s} {:s}", NAME, VERSION); - return; + return 0; } if matches.opt_present("help") || matches.free.is_empty() { @@ -59,7 +59,7 @@ pub fn uumain(args: Vec) { println!(""); println!("{:s}", getopts::usage("Update the access and modification times of \ each FILE to the current time.", opts)); - return; + return 0; } if matches.opt_present("date") && matches.opts_present(["reference".to_string(), "t".to_string()]) || @@ -131,6 +131,8 @@ pub fn uumain(args: Vec) { Err(e) => fail!("Unable to modify times\n{}", e.desc) } } + + 0 } fn stat(path: &Path, follow: bool) -> std::io::FileStat { diff --git a/tr/tr.rs b/tr/tr.rs index 5b906564d..03e78f251 100644 --- a/tr/tr.rs +++ b/tr/tr.rs @@ -147,9 +147,9 @@ fn usage(opts: &[OptGroup]) { } #[allow(dead_code)] -fn main() { uumain(os::args()); } +fn main() { os::set_exit_status(uumain(os::args())); } -pub fn uumain(args: Vec) { +pub fn uumain(args: Vec) -> int { let opts = [ getopts::optflag("c", "complement", "use the complement of SET1"), getopts::optflag("C", "", "same as -c"), @@ -161,25 +161,24 @@ pub fn uumain(args: Vec) { let matches = match getopts::getopts(args.tail(), opts) { Ok(m) => m, Err(err) => { - show_error!(1, "{}", err.to_err_msg()); - return; + show_error!("{}", err.to_err_msg()); + return 1; } }; if matches.opt_present("help") { usage(opts); - return; + return 0; } if matches.opt_present("version") { println!("{} {}", NAME, VERSION); - return; + return 0; } if matches.free.len() == 0 { usage(opts); - os::set_exit_status(1); - return; + return 1; } let dflag = matches.opt_present("d"); @@ -187,8 +186,8 @@ pub fn uumain(args: Vec) { let sets = matches.free; if cflag && !dflag { - show_error!(1, "-c is only supported with -d"); - return; + show_error!("-c is only supported with -d"); + return 1; } if dflag { @@ -199,4 +198,6 @@ pub fn uumain(args: Vec) { let set2 = expand_set(sets.get(1).as_slice()); tr(set1.as_slice(), set2.as_slice()); } + + 0 } diff --git a/truncate/truncate.rs b/truncate/truncate.rs index aada407e3..1f9f54925 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, @@ -47,9 +35,9 @@ enum TruncateMode { static NAME: &'static str = "truncate"; #[allow(dead_code)] -fn main() { uumain(os::args()); } +fn main() { os::set_exit_status(uumain(os::args())); } -pub fn uumain(args: Vec) { +pub fn uumain(args: Vec) -> int { let program = args.get(0).clone(); let opts = [ @@ -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_error!("missing an argument"); + return 1; } else { let no_create = matches.opt_present("no-create"); let io_blocks = matches.opt_present("io-blocks"); @@ -105,12 +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 + } } } + + 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())) { @@ -119,7 +112,13 @@ fn truncate(no_create: bool, _: bool, reference: Option, size: Option (stat.size, Reference), + Err(f) => { + show_error!("{}", f.to_str()); + return Err(1); + } + } } None => parse_size(size.unwrap().as_slice()) }; @@ -129,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, @@ -142,16 +147,19 @@ fn truncate(no_create: bool, _: bool, reference: Option, size: Option {} Err(f) => { - show_error!(1, "{}", f.to_str()); + show_error!("{}", f.to_str()); + return Err(1); } } } Err(f) => { - show_error!(1, "{}", f.to_str()); + show_error!("{}", f.to_str()); + return Err(1); } } } } + Ok(()) } fn parse_size(size: &str) -> (u64, TruncateMode) { diff --git a/tty/tty.rs b/tty/tty.rs index b34ff8565..1f10b9c34 100644 --- a/tty/tty.rs +++ b/tty/tty.rs @@ -35,9 +35,9 @@ extern { static NAME: &'static str = "tty"; #[allow(dead_code)] -fn main () { uumain(os::args()); } +fn main () { os::set_exit_status(uumain(os::args())); } -pub fn uumain(args: Vec) { +pub fn uumain(args: Vec) -> int { let options = [ optflag("s", "silent", "print nothing, only return an exit status") ]; @@ -49,7 +49,7 @@ pub fn uumain(args: Vec) { Err(f) => { println(f.to_err_msg().as_slice()); usage(); - return + return 2; } }; @@ -71,10 +71,9 @@ pub fn uumain(args: Vec) { } }; - os::set_exit_status(exit_code as int); + exit_code as int } fn usage () { safe_writeln!(&mut stderr() as &mut Writer, "usage: tty [-s]"); - os::set_exit_status(2); } diff --git a/uname/uname.rs b/uname/uname.rs index e9c4cefff..fc4cf3c8b 100644 --- a/uname/uname.rs +++ b/uname/uname.rs @@ -52,9 +52,9 @@ unsafe fn getuname() -> utsrust { static NAME: &'static str = "uname"; #[allow(dead_code)] -fn main() { uumain(os::args()); } +fn main() { os::set_exit_status(uumain(os::args())); } -pub fn uumain(args: Vec) { +pub fn uumain(args: Vec) -> int { let program = args.get(0).as_slice(); let opts = [ getopts::optflag("h", "help", "display this help and exit"), @@ -77,7 +77,7 @@ pub fn uumain(args: Vec) { println!(" {:s}", program); println!(""); print(getopts::usage("The uname utility writes symbols representing one or more system characteristics to the standard output.", opts).as_slice()); - return; + return 0; } let uname = unsafe { getuname() }; let mut output = String::new(); @@ -103,5 +103,7 @@ pub fn uumain(args: Vec) { output.push_str(uname.machine.as_slice()); output.push_str(" "); } - println!("{}", output.as_slice().trim_left()) + println!("{}", output.as_slice().trim_left()); + + 0 } diff --git a/unlink/unlink.rs b/unlink/unlink.rs index fc879bda7..aa07f0930 100644 --- a/unlink/unlink.rs +++ b/unlink/unlink.rs @@ -27,9 +27,9 @@ mod util; static NAME: &'static str = "unlink"; #[allow(dead_code)] -fn main() { uumain(os::args()); } +fn main() { os::set_exit_status(uumain(os::args())); } -pub fn uumain(args: Vec) { +pub fn uumain(args: Vec) -> int { let program = args.get(0).clone(); let opts = [ getopts::optflag("h", "help", "display this help and exit"), @@ -50,12 +50,12 @@ pub fn uumain(args: Vec) { println!(" {0:s} [FILE]... [OPTION]...", program); println!(""); print(getopts::usage("Unlink the file at [FILE].", opts).as_slice()); - return; + return 0; } if matches.opt_present("version") { println!("unlink 1.0.0"); - return; + return 0; } if matches.free.len() == 0 { @@ -86,4 +86,6 @@ pub fn uumain(args: Vec) { crash!(1, "cannot unlink '{0}': {1}", path.display(), e.desc); } } + + 0 } diff --git a/uptime/uptime.rs b/uptime/uptime.rs index f131fbf05..cdee621ec 100644 --- a/uptime/uptime.rs +++ b/uptime/uptime.rs @@ -48,9 +48,9 @@ extern { } #[allow(dead_code)] -fn main() { uumain(os::args()); } +fn main() { os::set_exit_status(uumain(os::args())); } -pub fn uumain(args: Vec) { +pub fn uumain(args: Vec) -> int { let program = args.get(0).clone(); let opts = [ getopts::optflag("v", "version", "output version information and exit"), @@ -62,7 +62,7 @@ pub fn uumain(args: Vec) { }; if matches.opt_present("version") { println!("uptime 1.0.0"); - return; + return 0; } if matches.opt_present("help") || matches.free.len() > 0 { println!("Usage:"); @@ -71,7 +71,7 @@ pub fn uumain(args: Vec) { print(getopts::usage("Print the current time, the length of time the system has been up,\n\ the number of users on the system, and the average number of jobs\n\ in the run queue over the last 1, 5 and 15 minutes.", opts).as_slice()); - return; + return 0; } print_time(); @@ -80,6 +80,8 @@ pub fn uumain(args: Vec) { print_uptime(upsecs); print_nusers(user_count); print_loadavg(); + + 0 } fn print_loadavg() { diff --git a/users/users.rs b/users/users.rs index fc048153d..5ff28476b 100644 --- a/users/users.rs +++ b/users/users.rs @@ -48,9 +48,9 @@ extern { static NAME: &'static str = "users"; #[allow(dead_code)] -fn main() { uumain(os::args()); } +fn main() { os::set_exit_status(uumain(os::args())); } -pub fn uumain(args: Vec) { +pub fn uumain(args: Vec) -> int { let program = args.get(0).as_slice(); let opts = [ getopts::optflag("h", "help", "display this help and exit"), @@ -69,12 +69,12 @@ pub fn uumain(args: Vec) { println!(" {:s} [OPTION]... [FILE]", program); println!(""); print(getopts::usage("Output who is currently logged in according to FILE.", opts).as_slice()); - return; + return 0; } if matches.opt_present("version") { println!("users 1.0.0"); - return; + return 0; } let mut filename = DEFAULT_FILE; @@ -83,6 +83,8 @@ pub fn uumain(args: Vec) { } exec(filename); + + 0 } fn exec(filename: &str) { diff --git a/uutils/uutils.rs b/uutils/uutils.rs index 8c708c123..e7949d92b 100644 --- a/uutils/uutils.rs +++ b/uutils/uutils.rs @@ -9,7 +9,6 @@ * file that was distributed with this source code. */ -extern crate collections; extern crate getopts; extern crate base64; @@ -54,14 +53,14 @@ extern crate whoami; extern crate yes; use std::os; -use collections::hashmap::HashMap; +use std::collections::hashmap::HashMap; static NAME: &'static str = "uutils"; static VERSION: &'static str = "1.0.0"; -fn util_map() -> HashMap<&str, fn(Vec)> { - fn uutrue(_: Vec) { os::set_exit_status(0); } - fn uufalse(_: Vec) { os::set_exit_status(1); } +fn util_map() -> HashMap<&str, fn(Vec) -> int> { + fn uutrue(_: Vec) -> int { 0 } + fn uufalse(_: Vec) -> int { 1 } let mut map = HashMap::new(); map.insert("base64", base64::uumain); @@ -109,7 +108,7 @@ fn util_map() -> HashMap<&str, fn(Vec)> { map } -fn usage(cmap: &HashMap<&str, fn(Vec)>) { +fn usage(cmap: &HashMap<&str, fn(Vec) -> int>) { println!("{} {}", NAME, VERSION); println!(""); println!("Usage:"); @@ -132,7 +131,7 @@ fn main() { let binary_as_util = binary.filename_str().unwrap(); if umap.contains_key(&binary_as_util) { let &uumain = umap.get(&binary_as_util); - uumain(args); + os::set_exit_status(uumain(args)); return } else if binary_as_util.starts_with("uutils") || binary_as_util.starts_with("busybox") { @@ -151,7 +150,7 @@ fn main() { let util = args.get(0).as_slice(); if umap.contains_key(&util) { let &uumain = umap.get(&util); - uumain(args.clone()); + os::set_exit_status(uumain(args.clone())); return } else if args.get(0).as_slice() == "--help" { // see if they want help on a specific util @@ -159,7 +158,7 @@ fn main() { let util = args.get(1).as_slice(); if umap.contains_key(&util) { let &uumain = umap.get(&util); - uumain(vec!["--help".to_string()]); + os::set_exit_status(uumain(vec!["--help".to_string()])); return } else { println!("{}: applet not found", util); @@ -168,6 +167,7 @@ fn main() { } } usage(&umap); + os::set_exit_status(0); return } else { println!("{}: applet not found", util); @@ -177,6 +177,7 @@ fn main() { } else { // no arguments provided usage(&umap); + os::set_exit_status(0); return } } diff --git a/wc/wc.rs b/wc/wc.rs index 9bf76cde2..cdbb7ada5 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"] @@ -34,9 +35,9 @@ struct Result { static NAME: &'static str = "wc"; #[allow(dead_code)] -fn main() { uumain(os::args()); } +fn main() { os::set_exit_status(uumain(os::args())); } -pub fn uumain(args: Vec) { +pub fn uumain(args: Vec) -> int { let program = args.get(0).clone(); let opts = [ getopts::optflag("c", "bytes", "print the byte counts"), @@ -62,12 +63,12 @@ pub fn uumain(args: Vec) { print(getopts::usage("Print newline, word and byte counts for each FILE", opts).as_slice()); println!(""); println!("With no FILE, or when FILE is -, read standard input."); - return; + return 0; } if matches.opt_present("version") { println!("wc 1.0.0"); - return; + return 0; } let mut files = matches.free.clone(); @@ -75,7 +76,12 @@ pub fn uumain(args: Vec) { files = vec!("-".to_string()); } - wc(files, &matches); + match wc(files, &matches) { + Ok(()) => ( /* pass */ ), + Err(e) => return e + } + + 0 } static CR: u8 = '\r' as u8; @@ -89,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; @@ -101,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; @@ -185,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); } + + Ok(()) } fn print_stats(filename: &str, line_count: uint, word_count: uint, char_count: uint, @@ -224,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)); + Ok(BufferedReader::new(reader)) }, Err(e) => { - show_error!(1, "wc: {0:s}: {1:s}", path, e.desc.to_str()); + show_error!("wc: {0:s}: {1:s}", path, e.desc.to_str()); + Err(1) } } - - None } diff --git a/whoami/whoami.rs b/whoami/whoami.rs index de5fe345c..1c237060e 100644 --- a/whoami/whoami.rs +++ b/whoami/whoami.rs @@ -42,9 +42,9 @@ unsafe fn getusername() -> String { static NAME: &'static str = "whoami"; #[allow(dead_code)] -fn main() { uumain(os::args()); } +fn main() { os::set_exit_status(uumain(os::args())); } -pub fn uumain(args: Vec) { +pub fn uumain(args: Vec) -> int { let program = args.get(0).as_slice(); let opts = [ getopts::optflag("h", "help", "display this help and exit"), @@ -61,14 +61,16 @@ pub fn uumain(args: Vec) { println!(" {:s}", program); println!(""); print(getopts::usage("print effective userid", opts).as_slice()); - return; + return 0; } if matches.opt_present("version") { println!("whoami 1.0.0"); - return; + return 0; } exec(); + + 0 } pub fn exec() { diff --git a/yes/yes.rs b/yes/yes.rs index b03b9ae5c..522732fb5 100644 --- a/yes/yes.rs +++ b/yes/yes.rs @@ -25,9 +25,9 @@ mod util; static NAME: &'static str = "yes"; #[allow(dead_code)] -fn main() { uumain(os::args()); } +fn main() { os::set_exit_status(uumain(os::args())); } -pub fn uumain(args: Vec) { +pub fn uumain(args: Vec) -> int { let program = args.get(0).clone(); let opts = [ getopts::optflag("h", "help", "display this help and exit"), @@ -46,11 +46,11 @@ pub fn uumain(args: Vec) { println!(" {0:s} [STRING]... [OPTION]...", program); println!(""); print(getopts::usage("Repeatedly output a line with all specified STRING(s), or 'y'.", opts).as_slice()); - return; + return 0; } if matches.opt_present("version") { println!("yes 1.0.0"); - return; + return 0; } let mut string = "y".to_string(); if !matches.free.is_empty() { @@ -58,6 +58,8 @@ pub fn uumain(args: Vec) { } exec(string.as_slice()); + + 0 } pub fn exec(string: &str) {