Skip to content

Commit

Permalink
Pass the test
Browse files Browse the repository at this point in the history
  • Loading branch information
ryuichiueda committed Jan 18, 2025
1 parent 6a0be4c commit 149ca07
Show file tree
Hide file tree
Showing 15 changed files with 70 additions and 48 deletions.
5 changes: 3 additions & 2 deletions src/core/builtins.rs
Original file line number Diff line number Diff line change
Expand Up @@ -135,8 +135,9 @@ pub fn command(core: &mut ShellCore, args: &mut Vec<String>) -> i32 {
let mut command = SimpleCommand::default();
let mut pipe = Pipe::new("".to_string());
command.args = words;
let pid = command.exec_command(core, &mut pipe);
proc_ctrl::wait_pipeline(core, vec![pid], false, false);
if let Ok(pid) = command.exec_command(core, &mut pipe) {
proc_ctrl::wait_pipeline(core, vec![pid], false, false);
}

core.db.exit_status
}
Expand Down
15 changes: 8 additions & 7 deletions src/elements/command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ pub mod r#while;
pub mod r#if;

use crate::{proc_ctrl, ShellCore, Feeder, Script};
use crate::error::exec::ExecError;
use crate::error::parse::ParseError;
use crate::utils::exit;
use self::arithmetic::ArithmeticCommand;
Expand Down Expand Up @@ -45,16 +46,15 @@ impl Clone for Box::<dyn Command> {
}

pub trait Command {
fn exec(&mut self, core: &mut ShellCore, pipe: &mut Pipe) -> Option<Pid> {
fn exec(&mut self, core: &mut ShellCore, pipe: &mut Pipe) -> Result<Option<Pid>, ExecError> {
if self.force_fork() || pipe.is_connected() {
self.fork_exec(core, pipe)
}else{
self.nofork_exec(core);
None
self.nofork_exec(core)
}
}

fn fork_exec(&mut self, core: &mut ShellCore, pipe: &mut Pipe) -> Option<Pid> {
fn fork_exec(&mut self, core: &mut ShellCore, pipe: &mut Pipe) -> Result<Option<Pid>, ExecError> {
match unsafe{unistd::fork()} {
Ok(ForkResult::Child) => {
core.initialize_as_subshell(Pid::from_raw(0), pipe.pgid);
Expand All @@ -65,22 +65,23 @@ pub trait Command {
Ok(ForkResult::Parent { child } ) => {
proc_ctrl::set_pgid(core, child, pipe.pgid);
pipe.parent_close();
Some(child)
Ok(Some(child))
},
Err(err) => panic!("sush(fatal): Failed to fork. {}", err),
}
}

fn nofork_exec(&mut self, core: &mut ShellCore) {
fn nofork_exec(&mut self, core: &mut ShellCore) -> Result<Option<Pid>, ExecError> {
if self.get_redirects().iter_mut().all(|r| r.connect(true, core)){
self.run(core, false);
}else{
core.db.exit_status = 1;
}
self.get_redirects().iter_mut().rev().for_each(|r| r.restore());
Ok(None)
}

fn run(&mut self, _: &mut ShellCore, fork: bool);
fn run(&mut self, _: &mut ShellCore, fork: bool) -> Result<(), ExecError>;
fn get_text(&self) -> String;
fn get_redirects(&mut self) -> &mut Vec<Redirect>;
fn set_force_fork(&mut self);
Expand Down
3 changes: 2 additions & 1 deletion src/elements/command/arithmetic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ pub struct ArithmeticCommand {
}

impl Command for ArithmeticCommand {
fn run(&mut self, core: &mut ShellCore, _: bool) {
fn run(&mut self, core: &mut ShellCore, _: bool) -> Result<(), ExecError> {
let exit_status = match self.eval(core).as_deref() {
Ok("0") => 1,
Ok(_) => 0,
Expand All @@ -26,6 +26,7 @@ impl Command for ArithmeticCommand {
},
};
core.db.exit_status = exit_status;
Ok(())
}

fn get_text(&self) -> String { self.text.clone() }
Expand Down
6 changes: 4 additions & 2 deletions src/elements/command/brace.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
//SPDX-License-Identifier: BSD-3-Clause

use crate::{ShellCore, Feeder, Script};
use crate::error::exec::ExecError;
use crate::error::parse::ParseError;
use crate::utils::exit;
use super::{Command, Redirect};
Expand All @@ -16,11 +17,12 @@ pub struct BraceCommand {
}

impl Command for BraceCommand {
fn run(&mut self, core: &mut ShellCore, _: bool) {
fn run(&mut self, core: &mut ShellCore, _: bool) -> Result<(), ExecError> {
match self.script {
Some(ref mut s) => {let _ = s.exec(core); },
Some(ref mut s) => s.exec(core)?,
_ => exit::internal(" (ParenCommand::exec)"),
}
Ok(())
}

fn get_text(&self) -> String { self.text.clone() }
Expand Down
6 changes: 4 additions & 2 deletions src/elements/command/case.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
//SPDX-License-Identifier: BSD-3-Clause

use crate::{ShellCore, Feeder, Script};
use crate::error::exec::ExecError;
use crate::error::parse::ParseError;
use crate::elements::command;
use crate::elements::word::Word;
Expand All @@ -18,7 +19,7 @@ pub struct CaseCommand {
}

impl Command for CaseCommand {
fn run(&mut self, core: &mut ShellCore, _: bool) {
fn run(&mut self, core: &mut ShellCore, _: bool) -> Result<(), ExecError> {
let mut next = false;
let word = self.word.clone().unwrap();

Expand All @@ -45,12 +46,13 @@ impl Command for CaseCommand {
let _ = e.1.exec(core);

if e.2 == ";;" {
return;
return Ok(());
}
next = e.2 == ";&";
}
}
}
Ok(())
}

fn get_text(&self) -> String { self.text.clone() }
Expand Down
4 changes: 3 additions & 1 deletion src/elements/command/for.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

use crate::{ShellCore, Feeder, Script};
use crate::error::exec;
use crate::error::exec::ExecError;
use crate::error::parse::ParseError;
use super::{Command, Redirect};
use crate::elements::command;
Expand All @@ -25,7 +26,7 @@ pub struct ForCommand {
}

impl Command for ForCommand {
fn run(&mut self, core: &mut ShellCore, _: bool) {
fn run(&mut self, core: &mut ShellCore, _: bool) -> Result<(), ExecError> {
core.loop_level += 1;

let ok = match self.has_arithmetic {
Expand All @@ -41,6 +42,7 @@ impl Command for ForCommand {
if core.loop_level == 0 {
core.break_counter = 0;
}
Ok(())
}

fn get_text(&self) -> String { self.text.clone() }
Expand Down
15 changes: 8 additions & 7 deletions src/elements/command/function_def.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
//SPDX-License-Identifier: BSD-3-Clause

use crate::{ShellCore, Feeder};
use crate::error::exec::ExecError;
use crate::error::parse::ParseError;
use super::{Command, Pipe, Redirect};
use crate::elements::command;
Expand All @@ -25,16 +26,16 @@ pub struct FunctionDefinition {
}

impl Command for FunctionDefinition {
fn exec(&mut self, core: &mut ShellCore, pipe: &mut Pipe) -> Option<Pid> {
fn exec(&mut self, core: &mut ShellCore, pipe: &mut Pipe) -> Result<Option<Pid>, ExecError> {
if self.force_fork || pipe.is_connected() {
return None;
return Ok(None);
}

core.db.functions.insert(self.name.to_string(), self.clone());
None
Ok(None)
}

fn run(&mut self, _: &mut ShellCore, _: bool) { }
fn run(&mut self, _: &mut ShellCore, _: bool) -> Result<(), ExecError> {Ok(())}
fn get_text(&self) -> String { self.text.clone() }
fn get_redirects(&mut self) -> &mut Vec<Redirect> { &mut self.redirects }
fn set_force_fork(&mut self) { self.force_fork = true; }
Expand All @@ -53,8 +54,8 @@ impl FunctionDefinition {
}
}

pub fn run_as_command(&mut self, args: &mut Vec<String>,
core: &mut ShellCore) -> Option<Pid> {
pub fn run_as_command(&mut self, args: &mut Vec<String>, core: &mut ShellCore)
-> Result<Option<Pid>, ExecError> {
let mut array = core.db.get_array_all("FUNCNAME");
array.insert(0, args[0].clone());
let _ = core.db.set_array("FUNCNAME", array, None);
Expand All @@ -78,7 +79,7 @@ impl FunctionDefinition {
let mut array = core.db.get_array_all("FUNCNAME");
array.remove(0);
let _ = core.db.set_array("FUNCNAME", array, None);
return pid;
pid
}

fn eat_name(feeder: &mut Feeder, ans: &mut Self, core: &mut ShellCore) -> bool {
Expand Down
8 changes: 5 additions & 3 deletions src/elements/command/if.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
//SPDX-License-Identifier: BSD-3-Clause

use crate::{ShellCore, Feeder, Script};
use crate::error::exec::ExecError;
use crate::error::parse::ParseError;
use crate::elements::command;
use crate::utils::exit;
Expand All @@ -18,19 +19,20 @@ pub struct IfCommand {
}

impl Command for IfCommand {
fn run(&mut self, core: &mut ShellCore, _: bool) {
fn run(&mut self, core: &mut ShellCore, _: bool) -> Result<(), ExecError> {
for i in 0..self.if_elif_scripts.len() {
let _ = self.if_elif_scripts[i].exec(core);
if core.db.exit_status == 0 {
let _ = self.then_scripts[i].exec(core);
return;
return Ok(());
}
}

match self.else_script.as_mut() {
Some(s) => {let _ = s.exec(core); },
Some(s) => s.exec(core)?,
_ => {},
}
Ok(())
}

fn get_text(&self) -> String { self.text.clone() }
Expand Down
8 changes: 5 additions & 3 deletions src/elements/command/paren.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
//SPDX-License-Identifier: BSD-3-Clause

use crate::{ShellCore, Feeder, Script};
use crate::error::exec::ExecError;
use crate::error::parse::ParseError;
use crate::utils::exit;
use super::{Command, Pipe, Redirect};
Expand All @@ -16,19 +17,20 @@ pub struct ParenCommand {
}

impl Command for ParenCommand {
fn exec(&mut self, core: &mut ShellCore, pipe: &mut Pipe) -> Option<Pid> {
fn exec(&mut self, core: &mut ShellCore, pipe: &mut Pipe) -> Result<Option<Pid>, ExecError> {
self.fork_exec(core, pipe)
}

fn run(&mut self, core: &mut ShellCore, fork: bool) {
fn run(&mut self, core: &mut ShellCore, fork: bool) -> Result<(), ExecError> {
if ! fork {
exit::internal(" (no fork for subshell)");
}

match self.script {
Some(ref mut s) => {let _ = s.exec(core); },
Some(ref mut s) => s.exec(core)?,
_ => exit::internal(" (ParenCommand::exec)"),
}
Ok(())
}

fn get_text(&self) -> String { self.text.clone() }
Expand Down
20 changes: 10 additions & 10 deletions src/elements/command/simple.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,17 +28,17 @@ pub struct SimpleCommand {


impl Command for SimpleCommand {
fn exec(&mut self, core: &mut ShellCore, pipe: &mut Pipe) -> Option<Pid> {
fn exec(&mut self, core: &mut ShellCore, pipe: &mut Pipe) -> Result<Option<Pid>, ExecError> {
let _ = core.db.set_param("LINENO", &self.lineno.to_string(), None);
if Self::break_continue_or_return(core) {
return None;
return Ok(None);
}

self.args.clear();
let mut words = self.words.to_vec();
if ! words.iter_mut().all(|w| self.set_arg(w, core).is_ok()){
core.word_eval_error = true;
return None;
return Err(ExecError::Other("word evaluation error".to_string()));
}

match self.args.len() {
Expand All @@ -47,7 +47,7 @@ impl Command for SimpleCommand {
}
}

fn run(&mut self, core: &mut ShellCore, fork: bool) {
fn run(&mut self, core: &mut ShellCore, fork: bool) -> Result<(), ExecError> {
core.db.push_local();
let layer = core.db.get_layer_num()-1;
let _ = self.set_local_params(core, layer);
Expand All @@ -69,6 +69,7 @@ impl Command for SimpleCommand {
if fork {
exit::normal(core);
}
Ok(())
}

fn get_text(&self) -> String { self.text.clone() }
Expand All @@ -83,9 +84,9 @@ impl SimpleCommand {
core.return_flag || core.break_counter > 0 || core.continue_counter > 0
}

pub fn exec_command(&mut self, core: &mut ShellCore, pipe: &mut Pipe) -> Option<Pid> {
pub fn exec_command(&mut self, core: &mut ShellCore, pipe: &mut Pipe) -> Result<Option<Pid>, ExecError> {
if Self::check_sigint(core) {
return None;
return Ok(None);
}

core.db.last_arg = self.args.last().unwrap().clone();
Expand All @@ -97,8 +98,7 @@ impl SimpleCommand {
&& ! core.db.functions.contains_key(&self.args[0]) ) {
self.fork_exec(core, pipe)
}else{
self.nofork_exec(core);
None
self.nofork_exec(core)
}
}

Expand All @@ -110,14 +110,14 @@ impl SimpleCommand {
false
}

fn exec_set_param(&mut self, core: &mut ShellCore) -> Option<Pid> {
fn exec_set_param(&mut self, core: &mut ShellCore) -> Result<Option<Pid>, ExecError> {
core.db.last_arg = String::new();
self.option_x_output(core);

self.substitutions.iter_mut()
.for_each(|s| {let _ = s.eval(core, None, false);});

None
Ok(None)
}

fn set_local_params(&mut self, core: &mut ShellCore, layer: usize) -> Result<(), ExecError> {
Expand Down
4 changes: 3 additions & 1 deletion src/elements/command/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
//SPDX-License-Identifier: BSD-3-Clause

use crate::{ShellCore, Feeder};
use crate::error::exec::ExecError;
use crate::error::parse::ParseError;
use super::{Command, Redirect};
use crate::elements::command;
Expand All @@ -18,7 +19,7 @@ pub struct TestCommand {
}

impl Command for TestCommand {
fn run(&mut self, core: &mut ShellCore, _: bool) {
fn run(&mut self, core: &mut ShellCore, _: bool) -> Result<(), ExecError> {
match self.cond.clone().unwrap().eval(core) {
Ok(CondElem::Ans(true)) => core.db.exit_status = 0,
Ok(CondElem::Ans(false)) => core.db.exit_status = 1,
Expand All @@ -31,6 +32,7 @@ impl Command for TestCommand {
core.db.exit_status = 2
},
} ;
Ok(())
}

fn get_text(&self) -> String { self.text.clone() }
Expand Down
Loading

0 comments on commit 149ca07

Please sign in to comment.