elementary shell behavior: can kick off a foreground process and

handle signals
This commit is contained in:
Ava Apples Affine 2023-03-24 18:14:33 -07:00
parent 3b1ae0efd5
commit 99cb9e5a2e
Signed by: affine
GPG key ID: 3A4645B8CF806069
17 changed files with 619 additions and 167 deletions

View file

@ -19,7 +19,7 @@ use crate::eval::eval;
use crate::lex::lex;
use crate::segment::{Ctr, Seg};
use crate::sym::{Args, SymTable, Symbol, ValueType};
use std::path::Path;
use std::path::{Path};
use std::fs;
use std::iter::FromIterator;
use std::env::{vars, var, current_dir};
@ -133,6 +133,22 @@ pub fn load_environment(syms: &mut SymTable) {
}
}
pub fn find_on_path(filename: String) -> Option<String> {
let mut prefixes = get_paths();
if let Ok(s) = current_dir() {
prefixes.push(String::from(s.to_str().unwrap()));
}
prefixes.push(String::from("/"));
for prefix in prefixes {
let candidate = Path::new(&prefix.clone()).join(filename.clone());
if candidate.exists() {
return Some(String::from(candidate.to_str().unwrap()))
}
}
None
}
pub fn run(filename: String, syms: &mut SymTable) -> Result<(), String> {
let script_read_res = fs::read_to_string(filename);
if script_read_res.is_err() {
@ -149,25 +165,30 @@ pub const RUN_DOCSTRING: &str = "Takes one string argument.
Attempts to find argument in PATH and attempts to call argument";
pub fn run_callback(ast: &Seg, syms: &mut SymTable) -> Result<Ctr, String> {
let mut prefixes = get_paths();
if let Ok(s) = current_dir() {
prefixes.push(String::from(s.to_str().unwrap()));
}
prefixes.push(String::from("/"));
if let Ctr::String(ref filename) = *ast.car {
for prefix in prefixes {
let candidate = Path::new(&prefix.clone()).join(filename);
if candidate.exists() {
if filename.ends_with(".rls") {
return run(String::from(candidate.to_str().unwrap()), syms)
.and(Ok(Ctr::None))
} else {
return Err("binary called, unimplemented!".to_string())
if filename.ends_with(".rls") {
if let Some(filepath) = find_on_path(filename.to_string()) {
return run(filepath, syms)
.and(Ok(Ctr::None))
} else {
let canonical_path_res = fs::canonicalize(filename);
if canonical_path_res.is_err() {
return Err(canonical_path_res
.err()
.unwrap()
.to_string());
}
let canonical_path = canonical_path_res.ok().unwrap();
return run(
canonical_path
.to_string_lossy()
.to_string(),
syms
).and(Ok(Ctr::None))
}
} else {
return Err("binary called, unimplemented!".to_string())
}
Err(format!("file {} not found", filename))
} else {
Err("impossible: not a string".to_string())
}