Skip to content
Snippets Groups Projects
Commit 2afa32c5 authored by Jeremy Soller's avatar Jeremy Soller
Browse files

Merge branch 'master' of https://github.com/redox-os/ion

parents 3d89453d 010932f1
No related branches found
No related tags found
No related merge requests found
...@@ -48,10 +48,39 @@ impl Job { ...@@ -48,10 +48,39 @@ impl Job {
} }
pub fn build_command(&mut self) -> Command { pub fn build_command(&mut self) -> Command {
let mut command = Command::new(&self.command); match CommandType::from(self.command.as_str()) {
for arg in self.args.drain(..).skip(1) { CommandType::Builtin => {
command.arg(arg); use std::env;
let process = env::current_exe().unwrap();
let mut command = Command::new(process);
command.arg("-c");
command.arg(&self.command);
for arg in self.args.drain(..).skip(1) {
command.arg(arg);
}
command
},
CommandType::External => {
let mut command = Command::new(&self.command);
for arg in self.args.drain(..).skip(1) {
command.arg(arg);
}
command
}
}
}
}
enum CommandType {
Builtin,
External
}
impl<'a> From<&'a str> for CommandType {
fn from(command: &'a str) -> CommandType {
match command {
"help" | "history" => CommandType::Builtin,
_ => CommandType::External
} }
command
} }
} }
...@@ -297,8 +297,6 @@ impl<'a> Shell<'a> { ...@@ -297,8 +297,6 @@ impl<'a> Shell<'a> {
/// To avoid infinite recursion when using aliases, the noalias boolean will be set the true /// To avoid infinite recursion when using aliases, the noalias boolean will be set the true
/// if an alias branch was executed. /// if an alias branch was executed.
fn run_pipeline(&mut self, pipeline: &mut Pipeline, noalias: bool) -> Option<i32> { fn run_pipeline(&mut self, pipeline: &mut Pipeline, noalias: bool) -> Option<i32> {
pipeline.expand(&self.variables, &self.directory_stack);
let command_start_time = SystemTime::now(); let command_start_time = SystemTime::now();
let mut exit_status = None; let mut exit_status = None;
...@@ -329,36 +327,48 @@ impl<'a> Shell<'a> { ...@@ -329,36 +327,48 @@ impl<'a> Shell<'a> {
} }
if !branched { if !branched {
pipeline.expand(&self.variables, &self.directory_stack);
// Branch if -> input == shell command i.e. echo // Branch if -> input == shell command i.e. echo
exit_status = if let Some(command) = builtins.get(pipeline.jobs[0].command.as_str()) { exit_status = if let Some(command) = builtins.get(pipeline.jobs[0].command.as_str()) {
// Run the 'main' of the command and set exit_status // Run the 'main' of the command and set exit_status
Some((*command.main)(pipeline.jobs[0].args.as_slice(), self)) if pipeline.jobs.len() == 1 {
Some((*command.main)(pipeline.jobs[0].args.as_slice(), self))
} else {
Some(execute_pipeline(pipeline))
}
// Branch else if -> input == shell function and set the exit_status // Branch else if -> input == shell function and set the exit_status
} else if let Some(function) = self.functions.get(pipeline.jobs[0].command.as_str()).cloned() { } else if let Some(function) = self.functions.get(pipeline.jobs[0].command.as_str()).cloned() {
if pipeline.jobs[0].args.len() - 1 == function.args.len() { if pipeline.jobs.len() == 1 {
let mut variables_backup: FnvHashMap<&str, Option<String>> = FnvHashMap::with_capacity_and_hasher ( if pipeline.jobs[0].args.len() - 1 == function.args.len() {
64, Default::default() let mut variables_backup: FnvHashMap<&str, Option<String>> = FnvHashMap::with_capacity_and_hasher (
); 64, Default::default()
for (name, value) in function.args.iter().zip(pipeline.jobs[0].args.iter().skip(1)) { );
variables_backup.insert(name, self.variables.get_var(name)); for (name, value) in function.args.iter().zip(pipeline.jobs[0].args.iter().skip(1)) {
self.variables.set_var(name, value); variables_backup.insert(name, self.variables.get_var(name));
} self.variables.set_var(name, value);
}
self.execute_statements(function.statements); self.execute_statements(function.statements);
for (name, value_option) in &variables_backup { for (name, value_option) in &variables_backup {
match *value_option { match *value_option {
Some(ref value) => self.variables.set_var(name, value), Some(ref value) => self.variables.set_var(name, value),
None => {self.variables.unset_var(name);}, None => {self.variables.unset_var(name);},
}
} }
None
} else {
let stderr = io::stderr();
let mut stderr = stderr.lock();
let _ = writeln!(stderr, "This function takes {} arguments, but you provided {}",
function.args.len(), pipeline.jobs[0].args.len()-1);
Some(NO_SUCH_COMMAND) // not sure if this is the right error code
} }
None
} else { } else {
let stderr = io::stderr(); let stderr = io::stderr();
let mut stderr = stderr.lock(); let mut stderr = stderr.lock();
let _ = writeln!(stderr, "This function takes {} arguments, but you provided {}", let _ = writeln!(stderr, "Function pipelining is not implemented yet");
function.args.len(), pipeline.jobs[0].args.len()-1); Some(FAILURE)
Some(NO_SUCH_COMMAND) // not sure if this is the right error code
} }
// If not a shell command or a shell function execute the pipeline and set the exit_status // If not a shell command or a shell function execute the pipeline and set the exit_status
} else { } else {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment