From 6eef8614722bc5c2d618711a5311fd8122765b53 Mon Sep 17 00:00:00 2001 From: Yuekai Jia Date: Sun, 2 Jul 2023 22:44:14 +0800 Subject: [PATCH] axstd: allow some apps to run with both std and axstd --- .github/workflows/build.yml | 33 ++++++++++++ Cargo.lock | 4 +- apps/display/Cargo.toml | 2 +- apps/display/src/display.rs | 2 +- apps/display/src/main.rs | 11 ++-- apps/exception/Cargo.toml | 2 +- apps/exception/src/main.rs | 7 +-- apps/fs/shell/Cargo.toml | 2 +- apps/fs/shell/src/cmd.rs | 89 ++++++++++++++++++++----------- apps/fs/shell/src/main.rs | 26 +++++++-- apps/helloworld/Cargo.toml | 2 +- apps/helloworld/src/main.rs | 11 ++-- apps/memtest/Cargo.toml | 2 +- apps/memtest/src/main.rs | 7 +-- apps/net/echoserver/Cargo.toml | 2 +- apps/net/echoserver/src/main.rs | 7 +-- apps/net/httpclient/Cargo.toml | 4 +- apps/net/httpclient/src/main.rs | 7 +-- apps/net/httpserver/Cargo.toml | 2 +- apps/net/httpserver/src/main.rs | 16 +++--- apps/net/udpserver/Cargo.toml | 2 +- apps/net/udpserver/src/main.rs | 27 +++++----- apps/task/parallel/Cargo.toml | 2 +- apps/task/parallel/src/main.rs | 7 +-- apps/task/priority/Cargo.toml | 2 +- apps/task/priority/src/main.rs | 7 +-- apps/task/sleep/Cargo.toml | 2 +- apps/task/sleep/src/main.rs | 7 +-- apps/task/yield/Cargo.toml | 2 +- apps/task/yield/src/main.rs | 7 +-- crates/axerrno/src/lib.rs | 8 +++ crates/axfs_vfs/src/structs.rs | 35 +++++++++++- ulib/axstd/src/lib.rs | 1 + ulib/axstd/src/net/socket_addr.rs | 2 + ulib/axstd/src/process.rs | 10 ++++ 35 files changed, 254 insertions(+), 105 deletions(-) create mode 100644 ulib/axstd/src/process.rs diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 214f55fe69..bde852b69f 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -91,3 +91,36 @@ jobs: run: make ARCH=${{ matrix.arch }} A=apps/c/udpserver - name: Build c/iperf run: make ARCH=${{ matrix.arch }} A=apps/c/iperf + + build-app-for-std: + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + os: [ubuntu-latest] + arch: [x86_64] + steps: + - uses: actions/checkout@v3 + - uses: actions-rs/toolchain@v1 + with: + profile: minimal + toolchain: ${{ env.rust-toolchain }} + - name: Build helloworld + run: cargo build -p arceos-helloworld + - name: Build memtest + run: cargo build -p arceos-memtest + - name: Build exception + run: cargo build -p arceos-exception + - name: Build task/yield + run: cargo build -p arceos-yield + - name: Build task/sleep + - name: Build fs/shell + run: cargo build -p arceos-shell + - name: Build net/echoserver + run: cargo build -p arceos-echoserver + - name: Build net/httpclient + run: cargo build -p arceos-httpclient + - name: Build net/httpserver + run: cargo build -p arceos-httpserver + - name: Build net/udpserver + run: cargo build -p arceos-udpserver diff --git a/Cargo.lock b/Cargo.lock index a6050501b5..fc240912c0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -39,8 +39,8 @@ dependencies = [ name = "arceos-display" version = "0.1.0" dependencies = [ + "axstd", "embedded-graphics", - "libax", ] [[package]] @@ -119,7 +119,7 @@ dependencies = [ name = "arceos-udpserver" version = "0.1.0" dependencies = [ - "libax", + "axstd", ] [[package]] diff --git a/apps/display/Cargo.toml b/apps/display/Cargo.toml index 4093f91ed2..4cfc2ba437 100644 --- a/apps/display/Cargo.toml +++ b/apps/display/Cargo.toml @@ -7,5 +7,5 @@ authors = ["Shiping Yuan "] # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -libax = { path = "../../ulib/libax", features = ["display"] } +axstd = { path = "../../ulib/axstd", features = ["display"], optional = true } embedded-graphics = "0.8" diff --git a/apps/display/src/display.rs b/apps/display/src/display.rs index 52f2a388b1..2df6928814 100644 --- a/apps/display/src/display.rs +++ b/apps/display/src/display.rs @@ -2,7 +2,7 @@ use embedded_graphics::pixelcolor::Rgb888; use embedded_graphics::prelude::{RgbColor, Size}; use embedded_graphics::{draw_target::DrawTarget, prelude::OriginDimensions}; -pub use libax::display::{framebuffer_flush, framebuffer_info, DisplayInfo}; +pub use std::os::arceos::display::{framebuffer_flush, framebuffer_info, DisplayInfo}; pub struct Display { size: Size, diff --git a/apps/display/src/main.rs b/apps/display/src/main.rs index 47582e0573..ecfe778377 100644 --- a/apps/display/src/main.rs +++ b/apps/display/src/main.rs @@ -1,9 +1,10 @@ -#![no_std] -#![no_main] +#![cfg_attr(feature = "axstd", no_std)] +#![cfg_attr(feature = "axstd", no_main)] -extern crate libax; -mod display; +#[cfg(feature = "axstd")] +extern crate axstd as std; +mod display; use display::*; use embedded_graphics::{ @@ -77,7 +78,7 @@ fn test_gpu() -> i32 { 0 } -#[no_mangle] +#[cfg_attr(feature = "axstd", no_mangle)] fn main() -> ! { test_gpu(); loop { diff --git a/apps/exception/Cargo.toml b/apps/exception/Cargo.toml index cbcadd408a..1c52e42ba4 100644 --- a/apps/exception/Cargo.toml +++ b/apps/exception/Cargo.toml @@ -7,4 +7,4 @@ authors = ["Yuekai Jia "] # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -axstd = { path = "../../ulib/axstd", features = ["paging"] } +axstd = { path = "../../ulib/axstd", features = ["paging"], optional = true } diff --git a/apps/exception/src/main.rs b/apps/exception/src/main.rs index 5ba562277c..e196cabd0a 100644 --- a/apps/exception/src/main.rs +++ b/apps/exception/src/main.rs @@ -1,6 +1,7 @@ -#![no_std] -#![no_main] +#![cfg_attr(feature = "axstd", no_std)] +#![cfg_attr(feature = "axstd", no_main)] +#[cfg(feature = "axstd")] extern crate axstd as std; use std::arch::asm; @@ -17,7 +18,7 @@ fn raise_break_exception() { } } -#[no_mangle] +#[cfg_attr(feature = "axstd", no_mangle)] fn main() { println!("Running exception tests..."); raise_break_exception(); diff --git a/apps/fs/shell/Cargo.toml b/apps/fs/shell/Cargo.toml index 4b2edbb3c6..13c7811eb0 100644 --- a/apps/fs/shell/Cargo.toml +++ b/apps/fs/shell/Cargo.toml @@ -15,4 +15,4 @@ default = [] # axfs_vfs = { path = "../../../crates/axfs_vfs", optional = true } # axfs_ramfs = { path = "../../../crates/axfs_ramfs", optional = true } # crate_interface = { path = "../../../crates/crate_interface", optional = true } -axstd = { path = "../../../ulib/axstd", features = ["alloc", "fs"] } +axstd = { path = "../../../ulib/axstd", features = ["alloc", "fs"], optional = true } diff --git a/apps/fs/shell/src/cmd.rs b/apps/fs/shell/src/cmd.rs index fd5fba24f6..bc96bb724d 100644 --- a/apps/fs/shell/src/cmd.rs +++ b/apps/fs/shell/src/cmd.rs @@ -1,21 +1,16 @@ -use std::fs::{self, File}; +use std::fs::{self, File, FileType}; use std::io::{self, prelude::*}; use std::{string::String, vec::Vec}; +#[cfg(all(not(feature = "axstd"), unix))] +use std::os::unix::fs::{FileTypeExt, PermissionsExt}; + macro_rules! print_err { - ($cmd: literal, $msg: literal) => { + ($cmd: literal, $msg: expr) => { println!("{}: {}", $cmd, $msg); }; - ($cmd: literal, $err: ident) => { - use io::Error::*; - println!("{}: {}", $cmd, $err.as_str()); - }; - ($cmd: literal, $arg: expr, $err: ident) => { - use io::Error::*; - println!("{}: {}: {}", $cmd, $arg, $err.as_str()); - }; - ($cmd: literal, $arg: expr, $msg: expr) => { - println!("{}: {}: {}", $cmd, $arg, $msg); + ($cmd: literal, $arg: expr, $err: expr) => { + println!("{}: {}: {}", $cmd, $arg, $err); }; } @@ -34,10 +29,47 @@ const CMD_TABLE: &[(&str, CmdHandler)] = &[ ("uname", do_uname), ]; +fn file_type_to_char(ty: FileType) -> char { + if ty.is_char_device() { + 'c' + } else if ty.is_block_device() { + 'b' + } else if ty.is_socket() { + 's' + } else if ty.is_fifo() { + 'p' + } else if ty.is_symlink() { + 'l' + } else if ty.is_dir() { + 'd' + } else if ty.is_file() { + '-' + } else { + '?' + } +} + +#[rustfmt::skip] +const fn file_perm_to_rwx(mode: u32) -> [u8; 9] { + let mut perm = [b'-'; 9]; + macro_rules! set { + ($bit:literal, $rwx:literal) => { + if mode & (1 << $bit) != 0 { + perm[8 - $bit] = $rwx + } + }; + } + + set!(2, b'r'); set!(1, b'w'); set!(0, b'x'); + set!(5, b'r'); set!(4, b'w'); set!(3, b'x'); + set!(8, b'r'); set!(7, b'w'); set!(6, b'x'); + perm +} + fn do_ls(args: &str) { let current_dir = std::env::current_dir().unwrap(); let args = if args.is_empty() { - current_dir.as_str() + path_to_str!(current_dir) } else { args }; @@ -47,8 +79,8 @@ fn do_ls(args: &str) { let metadata = fs::metadata(path)?; let size = metadata.len(); let file_type = metadata.file_type(); - let file_type_char = file_type.as_char(); - let rwx = metadata.permissions().rwx_buf(); + let file_type_char = file_type_to_char(file_type); + let rwx = file_perm_to_rwx(metadata.permissions().mode()); let rwx = unsafe { core::str::from_utf8_unchecked(&rwx) }; println!("{}{} {:>8} {}", file_type_char, rwx, size, entry); Ok(()) @@ -70,9 +102,10 @@ fn do_ls(args: &str) { entries.sort(); for entry in entries { - let path = String::from(name) + "/" + &entry; - if let Err(e) = show_entry_info(&path, &entry) { - print_err!("ls", path, e.as_str()); + let entry = path_to_str!(entry); + let path = String::from(name) + "/" + entry; + if let Err(e) = show_entry_info(&path, entry) { + print_err!("ls", path, e); } } Ok(()) @@ -83,7 +116,7 @@ fn do_ls(args: &str) { println!(); } if let Err(e) = list_one(name, name_count > 1) { - print_err!("ls", name, e.as_str()); + print_err!("ls", name, e); } } } @@ -109,7 +142,7 @@ fn do_cat(args: &str) { for fname in args.split_whitespace() { if let Err(e) = cat_one(fname) { - print_err!("cat", fname, e.as_str()); + print_err!("cat", fname, e); } } } @@ -138,7 +171,7 @@ fn do_echo(args: &str) { "\n", ]; if let Err(e) = echo_file(fname, &text_list) { - print_err!("echo", fname, e.as_str()); + print_err!("echo", fname, e); } } else { println!("{}", args) @@ -157,11 +190,7 @@ fn do_mkdir(args: &str) { for path in args.split_whitespace() { if let Err(e) = mkdir_one(path) { - print_err!( - "mkdir", - format_args!("cannot create directory '{path}'"), - e.as_str() - ); + print_err!("mkdir", format_args!("cannot create directory '{path}'"), e); } } } @@ -191,7 +220,7 @@ fn do_rm(args: &str) { continue; } if let Err(e) = rm_one(path, rm_dir) { - print_err!("rm", format_args!("cannot remove '{path}'"), e.as_str()); + print_err!("rm", format_args!("cannot remove '{path}'"), e); } } } @@ -202,7 +231,7 @@ fn do_cd(mut args: &str) { } if !args.contains(char::is_whitespace) { if let Err(e) = std::env::set_current_dir(args) { - print_err!("cd", args, e.as_str()); + print_err!("cd", args, e); } } else { print_err!("cd", "too many arguments"); @@ -211,7 +240,7 @@ fn do_cd(mut args: &str) { fn do_pwd(_args: &str) { let pwd = std::env::current_dir().unwrap(); - println!("{}", pwd); + println!("{}", path_to_str!(pwd)); } fn do_uname(_args: &str) { @@ -240,7 +269,7 @@ fn do_help(_args: &str) { fn do_exit(_args: &str) { println!("Bye~"); - std::thread::exit(0); + std::process::exit(0); } pub fn run_cmd(line: &[u8]) { diff --git a/apps/fs/shell/src/main.rs b/apps/fs/shell/src/main.rs index e0ba49cc73..2fcefb7c07 100644 --- a/apps/fs/shell/src/main.rs +++ b/apps/fs/shell/src/main.rs @@ -1,9 +1,23 @@ -#![no_std] -#![no_main] +#![cfg_attr(feature = "axstd", no_std)] +#![cfg_attr(feature = "axstd", no_main)] #[macro_use] +#[cfg(feature = "axstd")] extern crate axstd as std; +macro_rules! path_to_str { + ($path:expr) => {{ + #[cfg(not(feature = "axstd"))] + { + $path.to_str().unwrap() // Path/OsString -> &str + } + #[cfg(feature = "axstd")] + { + $path.as_str() // String -> &str + } + }}; +} + mod cmd; // #[cfg(feature = "use_ramfs")] @@ -20,10 +34,14 @@ const SPACE: u8 = b' '; const MAX_CMD_LEN: usize = 256; fn print_prompt() { - print!("arceos:{}$ ", std::env::current_dir().unwrap()); + print!( + "arceos:{}$ ", + path_to_str!(std::env::current_dir().unwrap()) + ); + std::io::stdout().flush().unwrap(); } -#[no_mangle] +#[cfg_attr(feature = "axstd", no_mangle)] fn main() { let mut stdin = std::io::stdin(); let mut stdout = std::io::stdout(); diff --git a/apps/helloworld/Cargo.toml b/apps/helloworld/Cargo.toml index 90018987ce..9b759ec55a 100644 --- a/apps/helloworld/Cargo.toml +++ b/apps/helloworld/Cargo.toml @@ -7,4 +7,4 @@ authors = ["Yuekai Jia "] # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -axstd = { path = "../../ulib/axstd" } +axstd = { path = "../../ulib/axstd", optional = true } diff --git a/apps/helloworld/src/main.rs b/apps/helloworld/src/main.rs index b742b84179..97161c8660 100644 --- a/apps/helloworld/src/main.rs +++ b/apps/helloworld/src/main.rs @@ -1,7 +1,10 @@ -#![no_std] -#![no_main] +#![cfg_attr(feature = "axstd", no_std)] +#![cfg_attr(feature = "axstd", no_main)] -#[no_mangle] +#[cfg(feature = "axstd")] +use axstd::println; + +#[cfg_attr(feature = "axstd", no_mangle)] fn main() { - axstd::println!("Hello, world!"); + println!("Hello, world!"); } diff --git a/apps/memtest/Cargo.toml b/apps/memtest/Cargo.toml index b3af5eaf6d..e6d4e71111 100644 --- a/apps/memtest/Cargo.toml +++ b/apps/memtest/Cargo.toml @@ -8,4 +8,4 @@ authors = ["Yuekai Jia "] [dependencies] rand = { version = "0.8", default-features = false, features = ["small_rng"] } -axstd = { path = "../../ulib/axstd", features = ["alloc", "paging"] } +axstd = { path = "../../ulib/axstd", features = ["alloc", "paging"], optional = true } diff --git a/apps/memtest/src/main.rs b/apps/memtest/src/main.rs index 2d7ffc6f27..1d3a081c25 100644 --- a/apps/memtest/src/main.rs +++ b/apps/memtest/src/main.rs @@ -1,7 +1,8 @@ -#![no_std] -#![no_main] +#![cfg_attr(feature = "axstd", no_std)] +#![cfg_attr(feature = "axstd", no_main)] #[macro_use] +#[cfg(feature = "axstd")] extern crate axstd as std; use rand::{rngs::SmallRng, RngCore, SeedableRng}; @@ -37,7 +38,7 @@ fn test_btree_map(rng: &mut impl RngCore) { println!("test_btree_map() OK!"); } -#[no_mangle] +#[cfg_attr(feature = "axstd", no_mangle)] fn main() { println!("Running memory tests..."); diff --git a/apps/net/echoserver/Cargo.toml b/apps/net/echoserver/Cargo.toml index d34fd856dc..7698bf0c11 100644 --- a/apps/net/echoserver/Cargo.toml +++ b/apps/net/echoserver/Cargo.toml @@ -7,4 +7,4 @@ authors = ["Yuekai Jia "] # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -axstd = { path = "../../../ulib/axstd", features = ["alloc", "multitask", "net"] } +axstd = { path = "../../../ulib/axstd", features = ["alloc", "multitask", "net"], optional = true } diff --git a/apps/net/echoserver/src/main.rs b/apps/net/echoserver/src/main.rs index 4f7f7f7433..0b92d435f2 100644 --- a/apps/net/echoserver/src/main.rs +++ b/apps/net/echoserver/src/main.rs @@ -1,7 +1,8 @@ -#![no_std] -#![no_main] +#![cfg_attr(feature = "axstd", no_std)] +#![cfg_attr(feature = "axstd", no_main)] #[macro_use] +#[cfg(feature = "axstd")] extern crate axstd as std; use std::io::{self, prelude::*}; @@ -54,7 +55,7 @@ fn accept_loop() -> io::Result<()> { } } -#[no_mangle] +#[cfg_attr(feature = "axstd", no_mangle)] fn main() { println!("Hello, echo server!"); accept_loop().expect("test echo server failed"); diff --git a/apps/net/httpclient/Cargo.toml b/apps/net/httpclient/Cargo.toml index 159f05d747..8efffa0328 100644 --- a/apps/net/httpclient/Cargo.toml +++ b/apps/net/httpclient/Cargo.toml @@ -7,8 +7,8 @@ authors = ["Yuekai Jia ", "Dashuai Wu io::Result<()> { Ok(()) } -#[no_mangle] +#[cfg_attr(feature = "axstd", no_mangle)] fn main() { println!("Hello, simple http client!"); client().expect("test http client failed"); diff --git a/apps/net/httpserver/Cargo.toml b/apps/net/httpserver/Cargo.toml index fac8d3cfe6..ba59e98205 100644 --- a/apps/net/httpserver/Cargo.toml +++ b/apps/net/httpserver/Cargo.toml @@ -7,4 +7,4 @@ authors = ["Yuekai Jia "] # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -axstd = { path = "../../../ulib/axstd", features = ["multitask", "net"] } +axstd = { path = "../../../ulib/axstd", features = ["alloc", "multitask", "net"], optional = true } diff --git a/apps/net/httpserver/src/main.rs b/apps/net/httpserver/src/main.rs index 04e4ec0071..6066bdf793 100644 --- a/apps/net/httpserver/src/main.rs +++ b/apps/net/httpserver/src/main.rs @@ -6,18 +6,22 @@ //! ab -n 5000 -c 20 http://X.X.X.X:5555/ //! ``` -#![no_std] -#![no_main] +#![cfg_attr(feature = "axstd", no_std)] +#![cfg_attr(feature = "axstd", no_main)] #[macro_use] +#[cfg(feature = "axstd")] extern crate axstd as std; -extern crate alloc; use std::io::{self, prelude::*}; use std::net::{TcpListener, TcpStream}; use std::thread; -const LOCAL_IP: &str = "10.0.2.15"; +const LOCAL_IP: &str = if cfg!(feature = "axstd") { + "10.0.2.15" +} else { + "0.0.0.0" +}; const LOCAL_PORT: u16 = 5555; macro_rules! header { @@ -63,7 +67,7 @@ fn http_server(mut stream: TcpStream) -> io::Result<()> { let mut buf = [0u8; 1024]; stream.read(&mut buf)?; - let reponse = alloc::format!(header!(), CONTENT.len(), CONTENT); + let reponse = format!(header!(), CONTENT.len(), CONTENT); stream.write_all(reponse.as_bytes())?; Ok(()) @@ -89,7 +93,7 @@ fn accept_loop() -> io::Result<()> { } } -#[no_mangle] +#[cfg_attr(feature = "axstd", no_mangle)] fn main() { println!("Hello, ArceOS HTTP server!"); accept_loop().expect("test HTTP server failed"); diff --git a/apps/net/udpserver/Cargo.toml b/apps/net/udpserver/Cargo.toml index b993a31e94..0c6b86a4aa 100644 --- a/apps/net/udpserver/Cargo.toml +++ b/apps/net/udpserver/Cargo.toml @@ -5,4 +5,4 @@ edition = "2021" authors = ["Dashuai Wu "] [dependencies] -libax = { path = "../../../ulib/libax", features = ["net"] } +axstd = { path = "../../../ulib/axstd", features = ["net"], optional = true } diff --git a/apps/net/udpserver/src/main.rs b/apps/net/udpserver/src/main.rs index 84e6d3eeb7..4302c88a5d 100644 --- a/apps/net/udpserver/src/main.rs +++ b/apps/net/udpserver/src/main.rs @@ -1,21 +1,22 @@ -#![no_std] -#![no_main] +#![cfg_attr(feature = "axstd", no_std)] +#![cfg_attr(feature = "axstd", no_main)] #[macro_use] -extern crate libax; -extern crate alloc; +#[cfg(feature = "axstd")] +extern crate axstd as std; -use core::str::FromStr; +use std::io; +use std::net::UdpSocket; -use libax::io; -use libax::net::{IpAddr, UdpSocket}; - -const LOCAL_IP: &str = "10.0.2.15"; +const LOCAL_IP: &str = if cfg!(feature = "axstd") { + "10.0.2.15" +} else { + "0.0.0.0" +}; const LOCAL_PORT: u16 = 5555; -fn receive_loop() -> io::Result { - let (addr, port) = (IpAddr::from_str(LOCAL_IP).unwrap(), LOCAL_PORT); - let socket = UdpSocket::bind((addr, port).into())?; +fn receive_loop() -> io::Result<()> { + let socket = UdpSocket::bind((LOCAL_IP, LOCAL_PORT))?; println!("listen on: {}", socket.local_addr().unwrap()); let mut buf = [0u8; 1024]; loop { @@ -33,7 +34,7 @@ fn receive_loop() -> io::Result { } } -#[no_mangle] +#[cfg_attr(feature = "axstd", no_mangle)] fn main() { println!("Hello, simple udp client!"); receive_loop().expect("test udp client failed"); diff --git a/apps/task/parallel/Cargo.toml b/apps/task/parallel/Cargo.toml index e690e3fe31..ffd20592a4 100644 --- a/apps/task/parallel/Cargo.toml +++ b/apps/task/parallel/Cargo.toml @@ -13,4 +13,4 @@ sched_cfs = ["axstd/sched_cfs"] [dependencies] rand = { version = "0.8", default-features = false, features = ["small_rng"] } -axstd = { path = "../../../ulib/axstd", features = ["alloc", "paging", "multitask", "irq"] } +axstd = { path = "../../../ulib/axstd", features = ["alloc", "paging", "multitask", "irq"], optional = true } diff --git a/apps/task/parallel/src/main.rs b/apps/task/parallel/src/main.rs index 28729a8f0e..58999468aa 100644 --- a/apps/task/parallel/src/main.rs +++ b/apps/task/parallel/src/main.rs @@ -1,7 +1,8 @@ -#![no_std] -#![no_main] +#![cfg_attr(feature = "axstd", no_std)] +#![cfg_attr(feature = "axstd", no_main)] #[macro_use] +#[cfg(feature = "axstd")] extern crate axstd as std; use rand::{rngs::SmallRng, RngCore, SeedableRng}; @@ -37,7 +38,7 @@ fn sqrt(n: &u64) -> u64 { } } -#[no_mangle] +#[cfg_attr(feature = "axstd", no_mangle)] fn main() { let mut rng = SmallRng::seed_from_u64(0xdead_beef); let vec = Arc::new((0..NUM_DATA).map(|_| rng.next_u64()).collect::>()); diff --git a/apps/task/priority/Cargo.toml b/apps/task/priority/Cargo.toml index 9b992501ab..6531c2b26d 100644 --- a/apps/task/priority/Cargo.toml +++ b/apps/task/priority/Cargo.toml @@ -12,4 +12,4 @@ sched_rr = ["axstd/sched_rr"] sched_cfs = ["axstd/sched_cfs"] [dependencies] -axstd = { path = "../../../ulib/axstd", features = ["alloc", "paging", "multitask"] } +axstd = { path = "../../../ulib/axstd", features = ["alloc", "paging", "multitask"], optional = true } diff --git a/apps/task/priority/src/main.rs b/apps/task/priority/src/main.rs index 34e3622868..575e8b826c 100644 --- a/apps/task/priority/src/main.rs +++ b/apps/task/priority/src/main.rs @@ -1,7 +1,8 @@ -#![no_std] -#![no_main] +#![cfg_attr(feature = "axstd", no_std)] +#![cfg_attr(feature = "axstd", no_main)] #[macro_use] +#[cfg(feature = "axstd")] extern crate axstd as std; use std::os::arceos::task::ax_set_current_priority; @@ -56,7 +57,7 @@ fn load(n: &u64) -> u64 { sum } -#[no_mangle] +#[cfg_attr(feature = "axstd", no_mangle)] fn main() { ax_set_current_priority(-20).ok(); diff --git a/apps/task/sleep/Cargo.toml b/apps/task/sleep/Cargo.toml index f07e85dc77..3449280758 100644 --- a/apps/task/sleep/Cargo.toml +++ b/apps/task/sleep/Cargo.toml @@ -11,4 +11,4 @@ default = [] sched_rr = ["axstd/sched_rr"] [dependencies] -axstd = { path = "../../../ulib/axstd", features = ["paging", "multitask", "irq"] } +axstd = { path = "../../../ulib/axstd", features = ["paging", "multitask", "irq"], optional = true } diff --git a/apps/task/sleep/src/main.rs b/apps/task/sleep/src/main.rs index 0cb5f85692..6cc4f0c2f4 100644 --- a/apps/task/sleep/src/main.rs +++ b/apps/task/sleep/src/main.rs @@ -1,7 +1,8 @@ -#![no_std] -#![no_main] +#![cfg_attr(feature = "axstd", no_std)] +#![cfg_attr(feature = "axstd", no_main)] #[macro_use] +#[cfg(feature = "axstd")] extern crate axstd as std; use std::sync::atomic::{AtomicUsize, Ordering}; @@ -12,7 +13,7 @@ const NUM_TASKS: usize = 5; static FINISHED_TASKS: AtomicUsize = AtomicUsize::new(0); -#[no_mangle] +#[cfg_attr(feature = "axstd", no_mangle)] fn main() { println!("Hello, main task!"); let now = Instant::now(); diff --git a/apps/task/yield/Cargo.toml b/apps/task/yield/Cargo.toml index 841dfec69b..ede7fd7f88 100644 --- a/apps/task/yield/Cargo.toml +++ b/apps/task/yield/Cargo.toml @@ -12,4 +12,4 @@ sched_rr = ["axstd/sched_rr"] sched_cfs = ["axstd/sched_cfs"] [dependencies] -axstd = { path = "../../../ulib/axstd", features = ["paging", "multitask"] } +axstd = { path = "../../../ulib/axstd", features = ["paging", "multitask"], optional = true } diff --git a/apps/task/yield/src/main.rs b/apps/task/yield/src/main.rs index b8115176c9..96d31ccd50 100644 --- a/apps/task/yield/src/main.rs +++ b/apps/task/yield/src/main.rs @@ -1,7 +1,8 @@ -#![no_std] -#![no_main] +#![cfg_attr(feature = "axstd", no_std)] +#![cfg_attr(feature = "axstd", no_main)] #[macro_use] +#[cfg(feature = "axstd")] extern crate axstd as std; use std::sync::atomic::{AtomicUsize, Ordering}; @@ -10,7 +11,7 @@ use std::thread; const NUM_TASKS: usize = 10; static FINISHED_TASKS: AtomicUsize = AtomicUsize::new(0); -#[no_mangle] +#[cfg_attr(feature = "axstd", no_mangle)] fn main() { for i in 0..NUM_TASKS { thread::spawn(move || { diff --git a/crates/axerrno/src/lib.rs b/crates/axerrno/src/lib.rs index c1688293d6..dc48de03a1 100644 --- a/crates/axerrno/src/lib.rs +++ b/crates/axerrno/src/lib.rs @@ -11,6 +11,8 @@ #![no_std] +use core::fmt; + mod linux_errno { include!(concat!(env!("OUT_DIR"), "/linux_errno.rs")); } @@ -193,6 +195,12 @@ impl AxError { } } +impl fmt::Display for AxError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{}", self.as_str()) + } +} + impl From for LinuxError { fn from(e: AxError) -> Self { use AxError::*; diff --git a/crates/axfs_vfs/src/structs.rs b/crates/axfs_vfs/src/structs.rs index 58c4783dbf..9d0dbfabac 100644 --- a/crates/axfs_vfs/src/structs.rs +++ b/crates/axfs_vfs/src/structs.rs @@ -87,6 +87,12 @@ impl VfsNodePerm { Self::from_bits_truncate(0o755) } + /// Returns the underlying raw `st_mode` bits that contain the standard + /// Unix permissions for this file. + pub const fn mode(&self) -> u32 { + self.bits() as u32 + } + /// Returns a 9-bytes string representation of the permission. /// /// For example, `0o755` is represented as `rwxr-xr-x`. @@ -139,16 +145,41 @@ impl VfsNodePerm { } impl VfsNodeType { - /// Whether the node is a file. + /// Tests whether this node type represents a regular file. pub const fn is_file(self) -> bool { matches!(self, Self::File) } - /// Whether the node is a directory. + /// Tests whether this node type represents a directory. pub const fn is_dir(self) -> bool { matches!(self, Self::Dir) } + /// Tests whether this node type represents a symbolic link. + pub const fn is_symlink(self) -> bool { + matches!(self, Self::SymLink) + } + + /// Returns `true` if this node type is a block device. + pub const fn is_block_device(self) -> bool { + matches!(self, Self::BlockDevice) + } + + /// Returns `true` if this node type is a char device. + pub const fn is_char_device(self) -> bool { + matches!(self, Self::CharDevice) + } + + /// Returns `true` if this node type is a fifo. + pub const fn is_fifo(self) -> bool { + matches!(self, Self::Fifo) + } + + /// Returns `true` if this node type is a socket. + pub const fn is_socket(self) -> bool { + matches!(self, Self::Socket) + } + /// Returns a character representation of the node type. /// /// For example, `d` for directory, `-` for regular file, etc. diff --git a/ulib/axstd/src/lib.rs b/ulib/axstd/src/lib.rs index 75897169f1..9afcb85ca1 100644 --- a/ulib/axstd/src/lib.rs +++ b/ulib/axstd/src/lib.rs @@ -61,6 +61,7 @@ pub use core::{arch, cell, cmp, hint, marker, mem, ops, ptr, slice, str}; pub mod env; pub mod io; pub mod os; +pub mod process; pub mod sync; pub mod thread; pub mod time; diff --git a/ulib/axstd/src/net/socket_addr.rs b/ulib/axstd/src/net/socket_addr.rs index d83b9249ba..0d0d2e9b88 100644 --- a/ulib/axstd/src/net/socket_addr.rs +++ b/ulib/axstd/src/net/socket_addr.rs @@ -82,6 +82,7 @@ impl ToSocketAddrs for &T { } #[cfg(not(feature = "dns"))] +#[doc(cfg(feature = "net"))] mod no_dns { use super::*; @@ -124,6 +125,7 @@ mod no_dns { } #[cfg(feature = "dns")] +#[doc(cfg(feature = "net"))] mod dns { use super::*; use alloc::{vec, vec::Vec}; diff --git a/ulib/axstd/src/process.rs b/ulib/axstd/src/process.rs new file mode 100644 index 0000000000..28349d2247 --- /dev/null +++ b/ulib/axstd/src/process.rs @@ -0,0 +1,10 @@ +//! A module for working with processes. +//! +//! Since ArceOS is a unikernel, there is no concept of processes. The +//! process-related functions will affect the entire system, such as [`exit`] +//! will shutdown the whole system. + +/// Shutdown the whole system. +pub fn exit(_exit_code: i32) -> ! { + arceos_api::sys::ax_terminate(); +}