diff --git a/Cargo.lock b/Cargo.lock
index c01bab3..00a939d 100644
@@ -127,6 +127,18 @@ dependencies = [
"generic-array",
]
+[[package]]
+name = "enum_dispatch"
+version = "0.3.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bd53b3fde38a39a06b2e66dc282f3e86191e53bd04cc499929c15742beae3df8"
+dependencies = [
+ "once_cell",
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
[[package]]
name = "float-cmp"
version = "0.9.0"
@@ -220,6 +232,7 @@ dependencies = [
"base64",
"bit_field 0.10.1",
"bootloader",
+ "enum_dispatch",
"float-cmp",
"hmac",
"lazy_static",
@@ -250,6 +263,12 @@ dependencies = [
"autocfg",
]
+[[package]]
+name = "once_cell"
+version = "1.8.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "692fcb63b64b1758029e0a96ee63e049ce8c5948587f2f7208df04625e5f6b56"
+
[[package]]
name = "opaque-debug"
version = "0.3.0"
diff --git a/Cargo.toml b/Cargo.toml
index f339e54..6758aad 100644
@@ -41,6 +41,7 @@ time = { version = "0.2.27", default-features = false }
uart_16550 = "0.2.15"
vte = "0.10.1"
x86_64 = "0.14.4"
+enum_dispatch = "0.3.7"
[package.metadata.bootimage]
test-success-exit-code = 33 # (0x10 << 1) | 1
diff --git a/src/api/fs.rs b/src/api/fs.rs
index 22dec6f..32b80ba 100644
@@ -1,5 +1,7 @@
use crate::sys;
use alloc::string::{String, ToString};
+use alloc::vec;
+use alloc::vec::Vec;
pub fn canonicalize(path: &str) -> Result<String, ()> {
match sys::process::env("HOME") {
@@ -31,6 +33,23 @@ pub fn read_to_string(path: &str) -> Result<String, ()> {
}
}
+pub fn read(path: &str) -> Result<Vec<u8>, ()> {
+ let path = match canonicalize(path) {
+ Ok(path) => path,
+ Err(_) => return Err(()),
+ };
+ match sys::fs::File::open(&path) {
+ Some(mut file) => {
+ let mut buf = vec![0; file.size()];
+ file.read(&mut buf);
+ Ok(buf)
+ },
+ None => {
+ Err(())
+ }
+ }
+}
+
pub fn write(path: &str, buf: &[u8]) -> Result<(), ()> {
let path = match canonicalize(path) {
Ok(path) => path,
diff --git a/src/api/mod.rs b/src/api/mod.rs
index 196423c..56ea98d 100644
@@ -19,6 +19,7 @@ macro_rules! println {
pub mod console;
pub mod font;
pub mod fs;
+pub mod process;
pub mod prompt;
pub mod regex;
pub mod syscall;
diff --git a/src/main.rs b/src/main.rs
index 83da2ba..4dc2668 100644
@@ -11,11 +11,6 @@ entry_point!(main);
fn main(boot_info: &'static BootInfo) -> ! {
moros::init(boot_info);
-
- let bin = include_bytes!("../dsk/bin/sleep");
- let process = sys::process::Process::create(bin);
- process.switch();
-
loop {
let bootrc = "/ini/boot.sh";
if sys::fs::File::open(bootrc).is_some() {
@@ -27,7 +22,6 @@ fn main(boot_info: &'static BootInfo) -> ! {
println!("MFS is not mounted to '/'");
}
println!("Running console in diskless mode");
-
usr::shell::main(&["shell"]);
}
}
diff --git a/src/sys/net/mod.rs b/src/sys/net/mod.rs
index e4dfe11..597e268 100644
@@ -1,34 +1,37 @@
+pub mod rtl8139;
+pub mod pcnet;
+
+use rtl8139::RTL8139;
+use pcnet::PCNET;
+
use alloc::sync::Arc;
use core::sync::atomic::{AtomicU64, Ordering};
use lazy_static::lazy_static;
use spin::Mutex;
-// TODO: Support dyn EthernetInterface
-pub type EthernetInterface<T> = smoltcp::iface::EthernetInterface<'static, T>;
-
-#[cfg(feature = "rtl8139")]
-pub mod rtl8139;
+use smoltcp::socket::SocketSet;
+use smoltcp::time::Instant;
+use core::time::Duration;
+use smoltcp::Result;
-#[cfg(feature = "rtl8139")]
lazy_static! {
- pub static ref IFACE: Mutex<Option<EthernetInterface<rtl8139::RTL8139>>> = Mutex::new(None);
+ pub static ref IFACE: Mutex<Option<EthernetInterface>> = Mutex::new(None);
}
-#[cfg(feature = "rtl8139")]
-pub fn init() {
- rtl8139::init();
+#[enum_dispatch]
+pub enum EthernetInterface {
+ RTL8139,
+ PCNET,
}
-#[cfg(feature = "pcnet")]
-pub mod pcnet;
-
-#[cfg(feature = "pcnet")]
-lazy_static! {
- pub static ref IFACE: Mutex<Option<EthernetInterface<pcnet::PCNET>>> = Mutex::new(None);
+#[enum_dispatch(EthernetInterface)]
+trait EthernetInterface {
+ pub fn poll(&mut self, sockets: &mut SocketSet<'_>,timestamp: Instant) -> Result<bool>;
+ pub fn poll_delay(&self, sockets: &SocketSet<'_>, timestamp: Instant) -> Option<Duration>;
}
-#[cfg(feature = "pcnet")]
pub fn init() {
+ rtl8139::init();
pcnet::init();
}
diff --git a/src/sys/net/pcnet.rs b/src/sys/net/pcnet.rs
index 587128a..0e5104d 100644
@@ -1,6 +1,7 @@
use crate::{sys, usr};
use crate::sys::allocator::PhysBuf;
use crate::sys::net::Stats;
+use crate::sys::net::EthernetInterface;
use alloc::collections::BTreeMap;
use alloc::sync::Arc;
@@ -456,7 +457,7 @@ pub fn init() {
routes(routes).
finalize();
- *sys::net::IFACE.lock() = Some(iface);
+ *sys::net::IFACE.lock() = Some(EthernetInterface::PCNET(iface));
}
}
}
diff --git a/src/sys/net/rtl8139.rs b/src/sys/net/rtl8139.rs
index 174e329..4eed684 100644
@@ -1,6 +1,8 @@
use crate::{sys, usr};
use crate::sys::allocator::PhysBuf;
use crate::sys::net::Stats;
+use crate::sys::net::EthernetInterface;
+
use alloc::collections::BTreeMap;
use alloc::vec::Vec;
use array_macro::array;
@@ -382,7 +384,7 @@ pub fn init() {
routes(routes).
finalize();
- *sys::net::IFACE.lock() = Some(iface);
+ *sys::net::IFACE.lock() = Some(EthernetInterface::RTL8139(iface));
}
//let irq = pci_device.interrupt_line;
diff --git a/src/sys/process.rs b/src/sys/process.rs
index bc9c201..d1eda01 100644
@@ -135,4 +135,3 @@ impl Process {
}
}
}
-
diff --git a/src/usr/install.rs b/src/usr/install.rs
index a67fc4f..6690aab 100644
@@ -38,6 +38,7 @@ pub fn main(_args: &[&str]) -> usr::shell::ExitCode {
create_dir("/usr"); // User directories
create_dir("/var"); // Variables
+ copy_file("/bin/sleep", include_bytes!("../../dsk/bin/sleep"));
copy_file("/ini/boot.sh", include_bytes!("../../dsk/ini/boot.sh"));
copy_file("/ini/banner.txt", include_bytes!("../../dsk/ini/banner.txt"));
copy_file("/ini/version.txt", include_bytes!("../../dsk/ini/version.txt"));
diff --git a/src/usr/shell.rs b/src/usr/shell.rs
index d261438..8a480a6 100644
@@ -1,5 +1,5 @@
use crate::api::prompt::Prompt;
-use crate::{sys, usr};
+use crate::{api, sys, usr};
use crate::api::console::Style;
use alloc::format;
use alloc::vec::Vec;
@@ -178,7 +178,14 @@ pub fn exec(cmd: &str) -> ExitCode {
"mem" | "memory" => usr::mem::main(&args),
"kb" | "keyboard" => usr::keyboard::main(&args),
"lisp" => usr::lisp::main(&args),
- _ => ExitCode::CommandUnknown,
+ cmd => {
+ if let Ok(process) = api::process::create(cmd) {
+ process.switch();
+ ExitCode::CommandSuccessful
+ } else {
+ ExitCode::CommandUnknown
+ }
+ }
}
}