diff options
Diffstat (limited to 'src/main.rs')
-rw-r--r-- | src/main.rs | 111 |
1 files changed, 33 insertions, 78 deletions
diff --git a/src/main.rs b/src/main.rs index 01e5fbd..e5e7a53 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,19 +1,11 @@ -use std::process::{Command, Stdio}; +use rustyline::error::ReadlineError; +use rustyline::Editor; mod builtins; +mod parser; mod prompt; -fn sigint_handler(dummy: i32) { - println!("sigint_handler: {}", dummy); -} - fn main() { - - unsafe { - // capture Ctrl+C (SIGINT) - libc::signal(libc::SIGINT, sigint_handler as libc::sighandler_t); - } - match std::fs::read_to_string("/etc/motd") { Ok(motd) => print!("{}", motd), Err(_) => {} @@ -22,77 +14,40 @@ fn main() { let prompt = prompt::Prompt::new().unwrap(); let mut cwd = std::env::current_dir().unwrap(); + // `()` can be used when no completer is required + let mut rl = Editor::<()>::new(); + /*if rl.load_history("history.txt").is_err() { + println!("No previous history."); + }*/ loop { - prompt.print(&cwd); - - let mut input = String::new(); - match std::io::stdin().read_line(&mut input) { - Ok(0) => return, // EOF - Ok(_) => {} // okay - Err(e) => { - eprintln!("error reading line: {}", e); - return; - } - }; - - let mut commands = input.trim().split(" | ").peekable(); - let mut previous_command: std::option::Option<std::process::Child> = None; - - while let Some(command) = commands.next() { - let mut parts = command.trim().split_whitespace(); - let command = match parts.next() { - Some(cmd) => cmd, - None => break, - }; - - let args = parts; - - match command { - "cd" => { - cwd = builtins::cd(args); - previous_command = None; - } - "exit" => return, - - command => { - let stdin = match previous_command { - None => Stdio::inherit(), - Some(cmd) => Stdio::from(cmd.stdout.unwrap()), - }; - let stdout = match commands.peek().is_some() { - true => Stdio::piped(), - false => Stdio::inherit(), - }; - - let child = Command::new(command) - .args(args) - .stdin(stdin) - .stdout(stdout) - .spawn(); - match child { - Ok(c) => previous_command = Some(c), - Err(e) => { - previous_command = None; - eprintln!("{}", e); - } + let readline = rl.readline(&prompt.print(&cwd)); + match readline { + Ok(line) => { + rl.add_history_entry(line.as_str()); + let commands = parser::parse(&line); + match commands[0] { + "cd" => { + cwd = builtins::cd(commands[1]); + } + _ => { + builtins::run(commands[0], &commands[1..]); } } + //println!("Line: {}", line); } - } - - if let Some(mut final_command) = previous_command { - match final_command.wait() { - Ok(ret) => match ret.code() { - Some(code) => { - if cfg!(debug_assertions) { - println!("exit code [{}]", code); - } - } - None => println!("Process termed by signal"), - }, - Err(e) => eprintln!("error waiting on final command: {}", e), + Err(ReadlineError::Interrupted) => { + println!("CTRL-C"); + continue; + } + Err(ReadlineError::Eof) => { + println!("CTRL-D"); + break; + } + Err(err) => { + println!("Error: {:?}", err); + break; } } - } // loop - + } + //rl.save_history("history.txt").unwrap(); } |