elementary shell behavior: can kick off a foreground process and
handle signals
This commit is contained in:
parent
3b1ae0efd5
commit
99cb9e5a2e
17 changed files with 619 additions and 167 deletions
53
src/run.rs
53
src/run.rs
|
|
@ -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())
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue