This MR finishes up all remaining Pre V1 goals

* add a posix exit() builtin
* improve separation of concerns regarding standard library structure
This commit is contained in:
Ava Apples Affine 2023-05-25 23:08:44 +00:00
parent b3c0b80ee6
commit 3bbea6bea0
9 changed files with 753 additions and 752 deletions

View file

@ -31,7 +31,7 @@ use {
run,
},
libc::{
sigaddset, sigemptyset, sigprocmask,
sigaddset, sigemptyset, sigprocmask, exit,
SIGINT, SIGCHLD, SIGTTOU, SIGTTIN, SIGQUIT, SIGTSTP,
SIG_BLOCK, SIG_UNBLOCK
},
@ -633,6 +633,19 @@ fn q_callback(_ast: &Seg, _syms: &SymTable, state: &mut ShellState) -> Result<Ct
Ok(Ctr::Integer(state.last_exit_code.into()))
}
const EXIT_DOCSTRING: &str = "Takes on integer input. calls libc exit() with given argument.";
fn exit_callback(ast: &Seg, _syms: &mut SymTable) -> Result<Ctr, Traceback> {
let mut ret = -1;
if let Ctr::Integer(i) = *ast.car {
ret = i;
} else {
eprintln!("WARNING: input was not an integer. Exiting -1.")
}
unsafe {
exit(ret as i32);
}
}
const BG_DOCSTRING: &str = "Calls a binary off disk with given arguments.
Arguments may be of any type except lambda. If a symbol is not defined it will be passed as a string.
first argument (command name) will be found on path (or an error returned).
@ -681,7 +694,7 @@ fn bg_callback(ast: &Seg, syms: &mut SymTable, state: &mut ShellState) -> Result
}
}
pub const FG_DOCSTRING: &str = "takes one argument (an integer).
const FG_DOCSTRING: &str = "takes one argument (an integer).
Integer is presumed to be a PID of a running background job.
If PID corresponds with a background job, fg will try to foreground it.
If PID is not a current running background job, fg will return an error.
@ -689,7 +702,7 @@ If PID is not a current running background job, fg will return an error.
Examples:
(bg vim) (fg 13871)
";
pub fn fg_callback(
fn fg_callback(
ast: &Seg,
_syms: &mut SymTable,
shell_state: &mut ShellState
@ -709,9 +722,9 @@ pub fn fg_callback(
}
}
pub const CD_DOCSTRING: &str =
const CD_DOCSTRING: &str =
"Expects 1 argument (a string). Changes to a new directory";
pub fn cd_callback(ast: &Seg, _syms: &mut SymTable) -> Result<Ctr, Traceback> {
fn cd_callback(ast: &Seg, _syms: &mut SymTable) -> Result<Ctr, Traceback> {
if let Ctr::String(ref dir) = *ast.car {
let dirp = Path::new(dir);
if let Err(s) = set_current_dir(&dirp) {
@ -913,4 +926,28 @@ pub fn load_posix_shell(syms: &mut SymTable, shell_state: Rc<RefCell<ShellState>
..Default::default()
},
);
syms.insert(
String::from("exit"),
Symbol {
name: String::from("exit"),
args: Args::Strict(vec![Type::Integer]),
conditional_branches: false,
docs: String::from(EXIT_DOCSTRING),
value: ValueType::Internal(Rc::new(exit_callback)),
..Default::default()
},
);
syms.insert(
"cd".to_string(),
Symbol {
name: String::from("cd"),
args: Args::Strict(vec![Type::String]),
conditional_branches: false,
docs: CD_DOCSTRING.to_string(),
value: ValueType::Internal(Rc::new(cd_callback)),
..Default::default()
},
);
}