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

Use exit code to set status var #360

Merged
merged 16 commits into from
Jun 29, 2022
1 change: 1 addition & 0 deletions doc/shell.md
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ Which is more efficient than doing:

- Name of the shell or the script: `$0`
- Script arguments: `$1`, `$2`, `$3`, `$4`, ...
- Exit code: `$?`
- Process environment variable: `$HOME`, ...
- Shell environment variable: `$foo`, ...

Expand Down
Binary file modified dsk/bin/clear
Binary file not shown.
Binary file modified dsk/bin/halt
Binary file not shown.
Binary file modified dsk/bin/hello
Binary file not shown.
Binary file modified dsk/bin/print
Binary file not shown.
Binary file modified dsk/bin/reboot
Binary file not shown.
Binary file modified dsk/bin/sleep
Binary file not shown.
6 changes: 3 additions & 3 deletions src/api/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ macro_rules! entry_point {
#[export_name = "_start"]
pub unsafe extern "sysv64" fn __impl_start(args_ptr: u64, args_len: usize) {
let args = core::slice::from_raw_parts(args_ptr as *const _, args_len);
let f: fn(&[&str]) -> usize = $path;
let code = f(args);
$crate::api::syscall::exit(code);
let f: fn(&[&str]) = $path;
f(args);
$crate::api::syscall::exit($crate::api::process::ExitCode::Success);
}
};
}
Expand Down
37 changes: 34 additions & 3 deletions src/api/process.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,39 @@
use crate::api::syscall;

pub fn spawn(path: &str, args: &[&str]) -> Result<(), ()> {
use core::convert::From;

#[derive(Copy, Clone, PartialEq, Eq)]
#[repr(u8)]
pub enum ExitCode {
Success = 0,
Failure = 1,
UsageError = 64,
DataError = 65,
OpenError = 128,
ReadError = 129,
ExecError = 130,
ShellExit = 255,
}

impl From<usize> for ExitCode {
fn from(code: usize) -> Self {
match code {
0 => ExitCode::Success,
64 => ExitCode::UsageError,
65 => ExitCode::DataError,
128 => ExitCode::OpenError,
129 => ExitCode::ReadError,
130 => ExitCode::ExecError,
255 => ExitCode::ShellExit,
_ => ExitCode::Failure,
}
}
}

pub fn spawn(path: &str, args: &[&str]) -> Result<(), ExitCode> {
if syscall::info(path).is_some() {
return syscall::spawn(path, args);
syscall::spawn(path, args)
} else {
Err(ExitCode::OpenError)
}
Err(())
}
51 changes: 26 additions & 25 deletions src/api/syscall.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
use crate::api::process::ExitCode;
use crate::syscall;
use crate::sys::syscall::number::*;
use crate::sys::fs::FileInfo;

pub fn exit(code: usize) -> usize {
unsafe { syscall!(EXIT, code as u64) }
pub fn exit(code: ExitCode) {
unsafe { syscall!(EXIT, code as usize) };
}

pub fn sleep(seconds: f64) {
Expand All @@ -14,10 +15,10 @@ pub fn delete(path: &str) -> Result<(), ()> {
let path_ptr = path.as_ptr() as usize;
let path_len = path.len() as usize;
let res = unsafe { syscall!(DELETE, path_ptr, path_len) } as isize;
if res.is_negative() {
Err(())
} else {
if res >= 0 {
Ok(())
} else {
Err(())
}
}

Expand All @@ -27,69 +28,69 @@ pub fn info(path: &str) -> Option<FileInfo> {
let mut info = FileInfo::new();
let stat_ptr = &mut info as *mut FileInfo as usize;
let res = unsafe { syscall!(INFO, path_ptr, path_len, stat_ptr) } as isize;
if res.is_negative() {
None
} else {
if res >= 0 {
Some(info)
} else {
None
}
}

pub fn open(path: &str, flags: usize) -> Option<usize> {
let ptr = path.as_ptr() as usize;
let len = path.len() as usize;
let res = unsafe { syscall!(OPEN, ptr, len, flags) } as isize;
if res.is_negative() {
None
} else {
if res >= 0 {
Some(res as usize)
} else {
None
}
}

pub fn dup(old_handle: usize, new_handle: usize) -> Option<usize> {
let res = unsafe { syscall!(DUP, old_handle, new_handle) } as isize;
if res.is_negative() {
None
} else {
if res >= 0 {
Some(res as usize)
} else {
None
}
}

pub fn read(handle: usize, buf: &mut [u8]) -> Option<usize> {
let ptr = buf.as_ptr() as usize;
let len = buf.len() as usize;
let res = unsafe { syscall!(READ, handle, ptr, len) } as isize;
if res.is_negative() {
None
} else {
if res >= 0 {
Some(res as usize)
} else {
None
}
}

pub fn write(handle: usize, buf: &[u8]) -> Option<usize> {
let ptr = buf.as_ptr() as usize;
let len = buf.len() as usize;
let res = unsafe { syscall!(WRITE, handle, ptr, len) } as isize;
if res.is_negative() {
None
} else {
if res >= 0 {
Some(res as usize)
} else {
None
}
}

pub fn close(handle: usize) {
unsafe { syscall!(CLOSE, handle as usize) };
}

pub fn spawn(path: &str, args: &[&str]) -> Result<(), ()> {
pub fn spawn(path: &str, args: &[&str]) -> Result<(), ExitCode> {
let path_ptr = path.as_ptr() as usize;
let path_len = path.len() as usize;
let args_ptr = args.as_ptr() as usize;
let args_len = args.len() as usize;
let res = unsafe { syscall!(SPAWN, path_ptr, path_len, args_ptr, args_len) } as isize;
if res.is_negative() {
Err(())
} else {
let res = unsafe { syscall!(SPAWN, path_ptr, path_len, args_ptr, args_len) };
if res == 0 {
Ok(())
} else {
Err(ExitCode::from(res))
}
}

Expand Down
3 changes: 1 addition & 2 deletions src/bin/clear.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ use moros::entry_point;

entry_point!(main);

fn main(_args: &[&str]) -> usize {
fn main(_args: &[&str]) {
syscall::write(1, b"\x1b[2J\x1b[1;1H"); // Clear screen and move cursor to top
0
}
2 changes: 1 addition & 1 deletion src/bin/halt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use moros::entry_point;

entry_point!(main);

fn main(_args: &[&str]) -> usize {
fn main(_args: &[&str]) {
syscall::write(1, b"\x1b[93m"); // Yellow
syscall::write(1, b"MOROS has reached its fate, the system is now halting.\n");
syscall::write(1, b"\x1b[0m"); // Reset
Expand Down
3 changes: 1 addition & 2 deletions src/bin/hello.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ use moros::entry_point;

entry_point!(main);

fn main(_args: &[&str]) -> usize {
fn main(_args: &[&str]) {
syscall::write(1, b"Hello, World!\n");
0
}
3 changes: 1 addition & 2 deletions src/bin/print.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use moros::api::syscall;

entry_point!(main);

fn main(args: &[&str]) -> usize {
fn main(args: &[&str]) {
let n = args.len();
for i in 1..n {
syscall::write(1, args[i].as_bytes());
Expand All @@ -15,5 +15,4 @@ fn main(args: &[&str]) -> usize {
}
}
syscall::write(1, b"\n");
0
}
2 changes: 1 addition & 1 deletion src/bin/reboot.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use moros::entry_point;

entry_point!(main);

fn main(_args: &[&str]) -> usize {
fn main(_args: &[&str]) {
syscall::write(1, b"\x1b[93m"); // Yellow
syscall::write(1, b"MOROS has reached its fate, the system is now rebooting.\n");
syscall::write(1, b"\x1b[0m"); // Reset
Expand Down
10 changes: 7 additions & 3 deletions src/bin/sleep.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,20 @@
#![no_main]

use moros::api::syscall;
use moros::api::process::ExitCode;
use moros::entry_point;

entry_point!(main);

fn main(args: &[&str]) -> usize {
fn main(args: &[&str]) {
if args.len() == 2 {
if let Ok(duration) = args[1].parse::<f64>() {
syscall::sleep(duration);
return 0
return;
} else {
syscall::exit(ExitCode::DataError);
}
} else {
syscall::exit(ExitCode::UsageError);
}
1
}
2 changes: 2 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@ extern crate alloc;
#[macro_use]
pub mod api;

#[macro_use]
pub mod sys;

pub mod usr;

use bootloader::BootInfo;
Expand Down
6 changes: 3 additions & 3 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ fn main(boot_info: &'static BootInfo) -> ! {
if let Some(cmd) = option_env!("MOROS_CMD") {
let prompt = usr::shell::prompt_string(true);
println!("{}{}", prompt, cmd);
usr::shell::exec(cmd);
usr::shell::exec(cmd).ok();
sys::acpi::shutdown();
} else {
user_boot();
Expand All @@ -27,15 +27,15 @@ fn main(boot_info: &'static BootInfo) -> ! {
fn user_boot() {
let script = "/ini/boot.sh";
if sys::fs::File::open(script).is_some() {
usr::shell::main(&["shell", script]);
usr::shell::main(&["shell", script]).ok();
} else {
if sys::fs::is_mounted() {
println!("Could not find '{}'", script);
} else {
println!("MFS is not mounted to '/'");
}
println!("Running console in diskless mode");
usr::shell::main(&["shell"]);
usr::shell::main(&["shell"]).ok();
}
}

Expand Down
5 changes: 3 additions & 2 deletions src/sys/process.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use crate::api::process::ExitCode;
use crate::sys::fs::{Resource, Device};
use crate::sys::console::Console;

Expand Down Expand Up @@ -248,7 +249,7 @@ impl Process {
}
}

pub fn spawn(bin: &[u8], args_ptr: usize, args_len: usize) -> Result<(), ()> {
pub fn spawn(bin: &[u8], args_ptr: usize, args_len: usize) -> Result<(), ExitCode> {
if let Ok(pid) = Self::create(bin) {
let proc = {
let table = PROCESS_TABLE.read();
Expand All @@ -257,7 +258,7 @@ impl Process {
proc.exec(args_ptr, args_len);
Ok(())
} else {
Err(())
Err(ExitCode::ExecError)
}
}

Expand Down
3 changes: 2 additions & 1 deletion src/sys/syscall/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
pub mod number;
pub mod service;

use crate::api::process::ExitCode;
use crate::sys;
use crate::sys::fs::FileInfo;

Expand All @@ -13,7 +14,7 @@ use core::arch::asm;
pub fn dispatcher(n: usize, arg1: usize, arg2: usize, arg3: usize, arg4: usize) -> usize {
match n {
number::EXIT => {
service::exit(arg1)
service::exit(ExitCode::from(arg1)) as usize
}
number::SLEEP => {
service::sleep(f64::from_bits(arg1 as u64));
Expand Down
21 changes: 14 additions & 7 deletions src/sys/syscall/service.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
use crate::sys;
use crate::api::process::ExitCode;
use crate::sys::fs::FileInfo;
use crate::sys::fs::FileIO;
use crate::sys::process::Process;

use alloc::vec;
use core::arch::asm;

pub fn exit(_code: usize) -> usize {
pub fn exit(code: ExitCode) -> ExitCode {
sys::process::exit();
0
code
}

pub fn sleep(seconds: f64) {
Expand Down Expand Up @@ -80,21 +82,26 @@ pub fn close(handle: usize) {
sys::process::delete_file_handle(handle);
}

pub fn spawn(path: &str, args_ptr: usize, args_len: usize) -> isize {
pub fn spawn(path: &str, args_ptr: usize, args_len: usize) -> ExitCode {
let path = match sys::fs::canonicalize(path) {
Ok(path) => path,
Err(_) => return -1,
Err(_) => return ExitCode::OpenError,
};
if let Some(mut file) = sys::fs::File::open(&path) {
let mut buf = vec![0; file.size()];
if let Ok(bytes) = file.read(&mut buf) {
buf.resize(bytes, 0);
if Process::spawn(&buf, args_ptr, args_len).is_ok() {
return 0;
if let Err(code) = Process::spawn(&buf, args_ptr, args_len) {
code
} else {
ExitCode::Success
}
} else {
ExitCode::ReadError
}
} else {
ExitCode::OpenError
}
-1
}

pub fn stop(code: usize) -> usize {
Expand Down
Loading