Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix various issues while reading files #307

Merged
merged 10 commits into from
Jan 25, 2022
2 changes: 2 additions & 0 deletions src/api/console.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
use crate::sys;
use core::fmt;

pub use crate::sys::console::{ETX_KEY, EOT_KEY};

#[derive(Clone, Copy)]
pub struct Style {
foreground: Option<usize>,
Expand Down
3 changes: 1 addition & 2 deletions src/api/fs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,7 @@ pub fn open_device(path: &str) -> Option<usize> {
pub fn create_device(path: &str, kind: DeviceType) -> Option<usize> {
let flags = OpenFlag::Create as usize | OpenFlag::Device as usize;
if let Some(handle) = syscall::open(path, flags) {
let buf = [kind as u8; 1];
syscall::write(handle, &buf);
syscall::write(handle, &kind.buf());
return Some(handle);
}
None
Expand Down
4 changes: 2 additions & 2 deletions src/api/prompt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,11 @@ impl Prompt {
let mut parser = Parser::new();
while let Some(c) = io::stdin().read_char() {
match c {
'\x03' => { // End of Text (^C)
console::ETX_KEY => { // End of Text (^C)
println!();
return Some(String::new());
},
'\x04' => { // End of Transmission (^D)
console::EOT_KEY => { // End of Transmission (^D)
println!();
return None;
},
Expand Down
8 changes: 4 additions & 4 deletions src/sys/console.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,10 +91,10 @@ pub fn is_raw_enabled() -> bool {
*RAW.lock()
}

const ETX_KEY: char = '\x03'; // End of Text
const EOT_KEY: char = '\x04'; // End of Transmission
const BS_KEY: char = '\x08'; // Backspace
const ESC_KEY: char = '\x1B'; // Escape
pub const ETX_KEY: char = '\x03'; // End of Text
pub const EOT_KEY: char = '\x04'; // End of Transmission
pub const BS_KEY: char = '\x08'; // Backspace
pub const ESC_KEY: char = '\x1B'; // Escape

pub fn key_handle(key: char) {
let mut stdin = STDIN.lock();
Expand Down
23 changes: 19 additions & 4 deletions src/sys/fs/device.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,12 @@ use super::dir::Dir;
use super::file::File;
use super::block::LinkedBlock;

use alloc::vec;
use alloc::vec::Vec;
use crate::sys::console::Console;
use crate::sys::random::Random;

#[derive(PartialEq, Clone, Copy)]
#[repr(u8)]
pub enum DeviceType {
File = 0,
Expand All @@ -14,6 +17,16 @@ pub enum DeviceType {
Null = 3,
}

impl DeviceType {
pub fn buf(self) -> Vec<u8> {
if self == DeviceType::Console {
vec![self as u8, 0, 0, 0] // 4 bytes
} else {
vec![self as u8] // 1 byte
}
}
}

#[derive(Debug, Clone)]
pub enum Device {
File(File),
Expand All @@ -22,16 +35,18 @@ pub enum Device {
Null,
}

impl Device {
fn new(i: u8) -> Self {
impl From<u8> for Device {
fn from(i: u8) -> Self {
match i {
i if i == DeviceType::Console as u8 => Device::Console(Console::new()),
i if i == DeviceType::Random as u8 => Device::Random(Random::new()),
i if i == DeviceType::Null as u8 => Device::Null,
_ => unimplemented!(),
}
}
}

impl Device {
pub fn create(pathname: &str) -> Option<Self> {
let pathname = realpath(pathname);
let dirname = dirname(&pathname);
Expand All @@ -53,7 +68,7 @@ impl Device {
if dir_entry.is_device() {
let block = LinkedBlock::read(dir_entry.addr());
let data = block.data();
return Some(Self::new(data[0]));
return Some(data[0].into());
}
}
}
Expand All @@ -67,7 +82,7 @@ impl FileIO for Device {
Device::File(io) => io.read(buf),
Device::Console(io) => io.read(buf),
Device::Random(io) => io.read(buf),
Device::Null => Ok(0),
Device::Null => Err(()),
}
}
fn write(&mut self, buf: &[u8]) -> Result<usize, ()> {
Expand Down
6 changes: 1 addition & 5 deletions src/sys/fs/dir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -242,11 +242,7 @@ impl FileIO for Dir {
break;
}
}
if i > 0 {
Ok(i)
} else {
Err(())
}
Ok(i)
}
fn write(&mut self, _buf: &[u8]) -> Result<usize, ()> {
Err(())
Expand Down
3 changes: 3 additions & 0 deletions src/usr/install.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ pub fn copy_files(verbose: bool) {
copy_file("/bin/sleep", include_bytes!("../../dsk/bin/sleep"), verbose);

create_dir("/dev/clk", verbose); // Clocks
create_dev("/dev/clk/uptime", DeviceType::File, verbose); // TODO
create_dev("/dev/clk/realtime", DeviceType::File, verbose); // TODO
create_dev("/dev/rtc", DeviceType::File, verbose); // TODO
create_dev("/dev/null", DeviceType::Null, verbose);
create_dev("/dev/random", DeviceType::Random, verbose);
create_dev("/dev/console", DeviceType::Console, verbose);
Expand Down
4 changes: 2 additions & 2 deletions src/usr/pow.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::usr;
use crate::api::console::Style;
use crate::api::{io, random};
use crate::api::{io, random, console};
use core::fmt;
use alloc::format;
use alloc::string::ToString;
Expand Down Expand Up @@ -34,7 +34,7 @@ impl Game {
let mut parser = Parser::new();
while let Some(c) = io::stdin().read_char() {
match c {
'q' | '\x03' | '\x04' => { // ^C and ^D
'q' | console::ETX_KEY | console::EOT_KEY => {
return;
},
c => {
Expand Down
28 changes: 25 additions & 3 deletions src/usr/read.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
use crate::{api, sys, usr};
use crate::api::console;
use crate::api::fs;
use crate::api::syscall;
use crate::sys::cmos::CMOS;

use alloc::borrow::ToOwned;
use alloc::vec::Vec;

Expand All @@ -18,6 +20,7 @@ pub fn main(args: &[&str]) -> usr::shell::ExitCode {
path = path.trim_end_matches('/');
}

// TODO: Create device drivers for `/dev` and `/net` hardcoded commands
match path {
"/dev/rtc" => {
let rtc = CMOS::new().rtc();
Expand Down Expand Up @@ -81,14 +84,33 @@ pub fn main(args: &[&str]) -> usr::shell::ExitCode {
} else if info.is_dir() {
usr::list::main(args)
} else if info.is_device() {
let is_console = info.size() == 4; // TODO: Improve device detection
loop {
if let Ok(bytes) = fs::read_to_bytes(path) {
print!("{}", bytes[0] as char);
}
if sys::console::end_of_text() {
println!();
return usr::shell::ExitCode::CommandSuccessful;
}
if let Ok(bytes) = fs::read_to_bytes(path) {
if is_console && bytes.len() == 1 {
match bytes[0] as char {
console::ETX_KEY => {
println!("^C");
return usr::shell::ExitCode::CommandSuccessful;
}
console::EOT_KEY => {
println!("^D");
return usr::shell::ExitCode::CommandSuccessful;
}
_ => {}
}
}
for b in bytes {
print!("{}", b as char);
}
} else {
eprintln!("Could not read '{}'", path);
return usr::shell::ExitCode::CommandError;
}
}
} else {
eprintln!("Could not read type of '{}'", path);
Expand Down