doc/readme #1
4 changed files with 52 additions and 13 deletions
18
README.md
18
README.md
|
@ -2,5 +2,21 @@
|
||||||
|
|
||||||
[![Please don't upload to GitHub](https://nogithub.codeberg.page/badge.svg)](https://nogithub.codeberg.page)
|
[![Please don't upload to GitHub](https://nogithub.codeberg.page/badge.svg)](https://nogithub.codeberg.page)
|
||||||
|
|
||||||
(The only purpose of this is learning Rust!)
|
## To-do
|
||||||
|
|
||||||
|
- [x] Read commands from `stdin`
|
||||||
|
- [ ] Exit with last child termination code
|
||||||
|
- [ ] Handle background jobs
|
||||||
|
- [ ] Handle pipes
|
||||||
|
- [ ] Handle double quotes
|
||||||
|
- [ ] Handle variables
|
||||||
|
- [ ] Interaction with environment variables
|
||||||
|
- [ ] Handle aliases
|
||||||
|
- [ ] Builtins
|
||||||
|
- [ ] `cd`
|
||||||
|
- [ ] `exit`
|
||||||
|
- [ ] Special variables
|
||||||
|
- [ ] `_`
|
||||||
|
- [ ] `PS1`
|
||||||
|
- [ ] Positional variables
|
||||||
|
- [ ] Handle signals
|
||||||
|
|
11
src/input.rs
11
src/input.rs
|
@ -1,5 +1,6 @@
|
||||||
use std::io as stdio;
|
use std::io as stdio;
|
||||||
use stdio::stdin;
|
use stdio::stdin;
|
||||||
|
use crate::parser;
|
||||||
|
|
||||||
pub struct Buffer {
|
pub struct Buffer {
|
||||||
buffer: String,
|
buffer: String,
|
||||||
|
@ -27,11 +28,11 @@ impl Buffer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_empty(&self) -> bool {
|
pub fn parse(&self) -> Option<Vec<String>> {
|
||||||
self.buffer.is_empty()
|
if ! self.buffer.is_empty() {
|
||||||
|
Some(parser::parse(&self.buffer))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_buffer(&self) -> &String {
|
|
||||||
&self.buffer
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
23
src/job.rs
Normal file
23
src/job.rs
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
use std::process::{
|
||||||
|
Command,
|
||||||
|
ExitStatus,
|
||||||
|
};
|
||||||
|
use std::io::{
|
||||||
|
Result,
|
||||||
|
Error,
|
||||||
|
ErrorKind,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub fn execute(mut argv: Vec<String>) -> Result<ExitStatus> {
|
||||||
|
let mut command = Command::new(&argv[0]);
|
||||||
|
argv.remove(0);
|
||||||
|
command.args(argv);
|
||||||
|
|
||||||
|
let child = command.spawn();
|
||||||
|
|
||||||
|
if child.is_ok() {
|
||||||
|
child.unwrap().wait()
|
||||||
|
} else {
|
||||||
|
Err(Error::new(ErrorKind::Other, "failed to spawn child process"))
|
||||||
|
}
|
||||||
|
}
|
11
src/main.rs
11
src/main.rs
|
@ -3,21 +3,20 @@ use std::process::exit;
|
||||||
mod input;
|
mod input;
|
||||||
mod output;
|
mod output;
|
||||||
mod parser;
|
mod parser;
|
||||||
|
mod job;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let mut buffer = input::Buffer::new();
|
let mut buffer = input::Buffer::new();
|
||||||
let mut bytes_read: usize = 1;
|
let mut bytes_read: usize = 1;
|
||||||
let mut command_line: String;
|
let mut argv: Option<Vec<String>>;
|
||||||
let mut argv: Vec<String>;
|
|
||||||
|
|
||||||
while bytes_read != 0 {
|
while bytes_read != 0 {
|
||||||
output::print_ps1();
|
output::print_ps1();
|
||||||
bytes_read = buffer.read_line();
|
bytes_read = buffer.read_line();
|
||||||
|
|
||||||
if ! buffer.is_empty() {
|
argv = buffer.parse();
|
||||||
command_line = buffer.get_buffer().to_string();
|
if argv.is_some() {
|
||||||
argv = parser::parse(&command_line);
|
let _ = job::execute(argv.unwrap());
|
||||||
println!("{:?}", argv);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Reference in a new issue