diff --git a/src/builtins/mod.rs b/src/builtins/mod.rs index bc7e5dad190908c1c12770e691a0ff0674d68af9..06dde43adca13840de476e608737507e8bdba0f2 100644 --- a/src/builtins/mod.rs +++ b/src/builtins/mod.rs @@ -24,64 +24,13 @@ use shell::job_control::{JobControl, ProcessState}; use shell::{self, Shell, FlowLogic, ShellHistory}; use shell::status::*; -#[cfg(target_os = "redox")] -fn exit_builtin() -> Builtin { - Builtin { - name: "exit", - help: "To exit the curent session", - main: Box::new(|args: &[&str], shell: &mut Shell| -> i32 { - let previous_status = shell.previous_status; - shell.exit( - args.get(1) - .and_then(|status| status.parse::<i32>().ok()) - .unwrap_or(previous_status), - ) - }), - } -} - -#[cfg(not(target_os = "redox"))] -fn exit_builtin() -> Builtin { - Builtin { - name: "exit", - help: "To exit the curent session", - main: Box::new(|args: &[&str], shell: &mut Shell| -> i32 { - use nix::sys::signal::{self, Signal as NixSignal}; - use libc::pid_t; - - // Kill all active background tasks before exiting the shell. - for process in shell.background.lock().unwrap().iter() { - if process.state != ProcessState::Empty { - let _ = signal::kill(process.pid as pid_t, Some(NixSignal::SIGTERM)); - } - } - let previous_status = shell.previous_status; - shell.exit( - args.get(1) - .and_then(|status| status.parse::<i32>().ok()) - .unwrap_or(previous_status), - ) - }), - } -} - /// Structure which represents a Terminal's command. /// This command structure contains a name, and the code which run the /// functionnality associated to this one, with zero, one or several argument(s). -/// # Example -/// ``` -/// let my_command = Builtin { -/// name: "my_command", -/// help: "Describe what my_command does followed by a newline showing usage", -/// main: box|args: &[&str], &mut Shell| -> i32 { -/// println!("Say 'hello' to my command! :-D"); -/// } -/// } -/// ``` pub struct Builtin { pub name: &'static str, pub help: &'static str, - pub main: Box<Fn(&[&str], &mut Shell) -> i32>, + pub main: fn(&[&str], &mut Shell) -> i32, } impl Builtin { @@ -113,7 +62,7 @@ impl Builtin { Builtin { name: $name, help: $help, - main: Box::new($func), + main: $func, } ); } @@ -155,7 +104,7 @@ impl Builtin { "Set or unset values of shell options and positional parameters." ); insert_builtin!("eval", builtin_eval, "evaluates the evaluated expression"); - commands.insert("exit", exit_builtin()); + insert_builtin!("exit", builtin_exit, "Exits the current session"); insert_builtin!( "wait", builtin_wait, @@ -426,3 +375,32 @@ fn builtin_help(args: &[&str], shell: &mut Shell) -> i32 { } SUCCESS } + +#[cfg(target_os = "redox")] +fn builtin_exit(args: &[&str], shell: &mut Shell) -> i32 { + let previous_status = shell.previous_status; + shell.exit( + args.get(1) + .and_then(|status| status.parse::<i32>().ok()) + .unwrap_or(previous_status), + ) +} + +#[cfg(not(target_os = "redox"))] +fn builtin_exit(args: &[&str], shell: &mut Shell) -> i32 { + use nix::sys::signal::{self, Signal as NixSignal}; + use libc::pid_t; + + // Kill all active background tasks before exiting the shell. + for process in shell.background.lock().unwrap().iter() { + if process.state != ProcessState::Empty { + let _ = signal::kill(process.pid as pid_t, Some(NixSignal::SIGTERM)); + } + } + let previous_status = shell.previous_status; + shell.exit( + args.get(1) + .and_then(|status| status.parse::<i32>().ok()) + .unwrap_or(previous_status), + ) +} diff --git a/src/shell/mod.rs b/src/shell/mod.rs index d1f889a9e76e0544bb7d9c039281c58c061b1e8c..890aac8da99aae6f88abfede63fe11ae6e8fbc47 100644 --- a/src/shell/mod.rs +++ b/src/shell/mod.rs @@ -182,7 +182,7 @@ impl<'a> Shell<'a> { let small: SmallVec<[&str; 4]> = borrowed.iter() .map(|x| x as &str) .collect(); - Some((*command.main)(&small, self)) + Some((command.main)(&small, self)) } else { Some(self.execute_pipeline(pipeline)) } @@ -268,7 +268,7 @@ impl<'a> Shell<'a> { let mut new_args: SmallVec<[&str; 4]> = SmallVec::new(); new_args.push("cd"); new_args.extend(pipeline.jobs[0].args.iter().map(|x| x as &str)); - Some((*builtins.get("cd").unwrap().main)(&new_args, self)) + Some((builtins.get("cd").unwrap().main)(&new_args, self)) } else { Some(self.execute_pipeline(pipeline)) };