Initial commit
This commit is contained in:
commit
2b51b024f7
5
.cargo/config.toml
Normal file
5
.cargo/config.toml
Normal file
@ -0,0 +1,5 @@
|
||||
[build]
|
||||
target = "x86_64-unknown-mikros"
|
||||
|
||||
[install]
|
||||
root = "../os_build/sysroot"
|
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
/target
|
391
Cargo.lock
generated
Normal file
391
Cargo.lock
generated
Normal file
@ -0,0 +1,391 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 4
|
||||
|
||||
[[package]]
|
||||
name = "atomic-polyfill"
|
||||
version = "1.0.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8cf2bce30dfe09ef0bfaef228b9d414faaf7e563035494d7fe092dba54b300f4"
|
||||
dependencies = [
|
||||
"critical-section",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26"
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "2.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "byteorder"
|
||||
version = "1.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "cobs"
|
||||
version = "0.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "67ba02a97a2bd10f4b59b25c7973101c79642302776489e030cd13cdab09ed15"
|
||||
|
||||
[[package]]
|
||||
name = "critical-section"
|
||||
version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "790eea4361631c5e7d22598ecd5723ff611904e3344ce8720784c93e3d83d40b"
|
||||
|
||||
[[package]]
|
||||
name = "dir_rpc"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"parking_lot",
|
||||
"postcard",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "embedded-io"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ef1a6892d9eef45c8fa6b9e0086428a2cca8491aca8f787c534a3d6d0bcb3ced"
|
||||
|
||||
[[package]]
|
||||
name = "embedded-io"
|
||||
version = "0.6.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "edd0f118536f44f5ccd48bcb8b111bdc3de888b58c74639dfb034a357d0f206d"
|
||||
|
||||
[[package]]
|
||||
name = "file_rpc"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"parking_lot",
|
||||
"postcard",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fs_rpc"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"parking_lot",
|
||||
"postcard",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hash32"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b0c35f58762feb77d74ebe43bdbc3210f09be9fe6742234d573bacc26ed92b67"
|
||||
dependencies = [
|
||||
"byteorder",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "heapless"
|
||||
version = "0.7.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cdc6457c0eb62c71aac4bc17216026d8410337c4126773b9c5daba343f17964f"
|
||||
dependencies = [
|
||||
"atomic-polyfill",
|
||||
"hash32",
|
||||
"rustc_version",
|
||||
"serde",
|
||||
"spin",
|
||||
"stable_deref_trait",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.164"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "433bfe06b8c75da9b2e3fbea6e5329ff87748f0b144ef75306e674c3f6f7c13f"
|
||||
|
||||
[[package]]
|
||||
name = "lock_api"
|
||||
version = "0.4.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"scopeguard",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "parking_lot"
|
||||
version = "0.12.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27"
|
||||
dependencies = [
|
||||
"lock_api",
|
||||
"parking_lot_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "parking_lot_core"
|
||||
version = "0.9.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"redox_syscall",
|
||||
"smallvec",
|
||||
"windows-targets",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "postcard"
|
||||
version = "1.0.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5f7f0a8d620d71c457dd1d47df76bb18960378da56af4527aaa10f515eee732e"
|
||||
dependencies = [
|
||||
"cobs",
|
||||
"embedded-io 0.4.0",
|
||||
"embedded-io 0.6.1",
|
||||
"heapless",
|
||||
"postcard-derive",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "postcard-derive"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0239fa9c1d225d4b7eb69925c25c5e082307a141e470573fbbe3a817ce6a7a37"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.89"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f139b0662de085916d1fb67d2b4169d1addddda1919e696f3252b740b629986e"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.37"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.5.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9b6dfecf2c74bce2466cabf93f6664d6998a69eb21e39f4207930065b27b771f"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustc_version"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92"
|
||||
dependencies = [
|
||||
"semver",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "scopeguard"
|
||||
version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
|
||||
|
||||
[[package]]
|
||||
name = "semver"
|
||||
version = "1.0.23"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b"
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.210"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.210"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.87",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "smallvec"
|
||||
version = "1.13.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67"
|
||||
|
||||
[[package]]
|
||||
name = "spin"
|
||||
version = "0.9.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67"
|
||||
dependencies = [
|
||||
"lock_api",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "stable_deref_trait"
|
||||
version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.109"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.87"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "25aa4ce346d03a6dcd68dd8b4010bcb74e54e62c90c573f394c46eae99aba32d"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syslog_rpc"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"parking_lot",
|
||||
"postcard",
|
||||
"syslog_structs",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syslog_structs"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tmpfs"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"dir_rpc",
|
||||
"file_rpc",
|
||||
"fs_rpc",
|
||||
"parking_lot",
|
||||
"syslog_rpc",
|
||||
"vfs_rpc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe"
|
||||
|
||||
[[package]]
|
||||
name = "vfs_rpc"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"parking_lot",
|
||||
"postcard",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-targets"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
|
||||
dependencies = [
|
||||
"windows_aarch64_gnullvm",
|
||||
"windows_aarch64_msvc",
|
||||
"windows_i686_gnu",
|
||||
"windows_i686_gnullvm",
|
||||
"windows_i686_msvc",
|
||||
"windows_x86_64_gnu",
|
||||
"windows_x86_64_gnullvm",
|
||||
"windows_x86_64_msvc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_gnullvm"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnullvm"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnullvm"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
|
21
Cargo.toml
Normal file
21
Cargo.toml
Normal file
@ -0,0 +1,21 @@
|
||||
[package]
|
||||
name = "tmpfs"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
dir_rpc = { version = "0.1.0", path = "../dir_rpc" }
|
||||
file_rpc = { version = "0.1.0", path = "../file_rpc" }
|
||||
fs_rpc = { version = "0.1.0", path = "../fs_rpc" }
|
||||
parking_lot = "0.12.3"
|
||||
syslog_rpc = { version = "0.1.0", path = "../syslog/syslog_rpc" }
|
||||
vfs_rpc = { version = "0.1.0", path = "../vfs/vfs_rpc" }
|
||||
|
||||
[profile.release]
|
||||
strip = true
|
||||
lto = true
|
||||
opt-level = "s"
|
||||
|
||||
[patch.crates-io]
|
||||
serde = { path = "../serde/serde" }
|
||||
serde_derive = { path = "../serde/serde_derive" }
|
2
rust-toolchain.toml
Normal file
2
rust-toolchain.toml
Normal file
@ -0,0 +1,2 @@
|
||||
[toolchain]
|
||||
channel = "dev-x86_64-unknown-mikros"
|
144
src/main.rs
Normal file
144
src/main.rs
Normal file
@ -0,0 +1,144 @@
|
||||
mod tempfs;
|
||||
|
||||
use std::{
|
||||
borrow::Cow,
|
||||
os::mikros::{ipc, syscalls, Errno, FileOpenMode},
|
||||
sync::Arc,
|
||||
};
|
||||
|
||||
use parking_lot::Mutex;
|
||||
use tempfs::TempFs;
|
||||
|
||||
#[derive(Clone)]
|
||||
struct Serv {
|
||||
mounts: Arc<Mutex<Vec<TempFs>>>,
|
||||
}
|
||||
|
||||
impl fs_rpc::Server for Serv {
|
||||
fn mount(&self, _dev: &std::path::Path) -> Result<u64, Errno> {
|
||||
let mut mounts = self.mounts.lock();
|
||||
if mounts.len() == u32::MAX as usize {
|
||||
return Err(Errno::ENOMEM);
|
||||
}
|
||||
mounts.push(TempFs::new());
|
||||
Ok((mounts.len() - 1) as u64)
|
||||
}
|
||||
|
||||
fn open(
|
||||
&self,
|
||||
path: &std::path::Path,
|
||||
mode: FileOpenMode,
|
||||
mount_id: u64,
|
||||
) -> Result<(Option<u64>, u64), Errno> {
|
||||
let mut mounts = self.mounts.lock();
|
||||
let mount = mounts.get_mut(mount_id as usize).ok_or(Errno::EBADF)?;
|
||||
let fd = mount.open(path, mode)?;
|
||||
Ok((None, (fd as u64) | (mount_id << 32)))
|
||||
}
|
||||
|
||||
fn open_dir(&self, path: &std::path::Path, mount_id: u64) -> Result<(Option<u64>, u64), Errno> {
|
||||
let mut mounts = self.mounts.lock();
|
||||
let mount = mounts.get_mut(mount_id as usize).ok_or(Errno::EBADF)?;
|
||||
let fd = mount.open_dir(path)?;
|
||||
Ok((None, (fd as u64) | (mount_id << 32)))
|
||||
}
|
||||
}
|
||||
|
||||
impl file_rpc::Server for Serv {
|
||||
fn read(&self, fd: u64, len: usize) -> Result<Cow<'_, [u8]>, Errno> {
|
||||
let mount_id = fd >> 32;
|
||||
let fd = fd as u32;
|
||||
let mut mounts = self.mounts.lock();
|
||||
let mount = mounts.get_mut(mount_id as usize).ok_or(Errno::EBADF)?;
|
||||
mount.read(fd, len).map(|buf| buf.into())
|
||||
}
|
||||
|
||||
fn write(&self, fd: u64, data: &[u8]) -> Result<(), Errno> {
|
||||
let mount_id = fd >> 32;
|
||||
let fd = fd as u32;
|
||||
let mut mounts = self.mounts.lock();
|
||||
let mount = mounts.get_mut(mount_id as usize).ok_or(Errno::EBADF)?;
|
||||
mount.write(fd, data)
|
||||
}
|
||||
|
||||
fn close(&self, fd: u64) -> Result<(), Errno> {
|
||||
let mount_id = fd >> 32;
|
||||
let fd = fd as u32;
|
||||
let mut mounts = self.mounts.lock();
|
||||
let mount = mounts.get_mut(mount_id as usize).ok_or(Errno::EBADF)?;
|
||||
mount.close(fd)
|
||||
}
|
||||
|
||||
fn size(&self, fd: u64) -> Result<u64, Errno> {
|
||||
let mount_id = fd >> 32;
|
||||
let fd = fd as u32;
|
||||
let mounts = self.mounts.lock();
|
||||
let mount = mounts.get(mount_id as usize).ok_or(Errno::EBADF)?;
|
||||
mount.size(fd)
|
||||
}
|
||||
|
||||
fn dup(&self, fd: u64) -> Result<u64, Errno> {
|
||||
let mount_id = fd >> 32;
|
||||
let fd = fd as u32;
|
||||
let mut mounts = self.mounts.lock();
|
||||
let mount = mounts.get_mut(mount_id as usize).ok_or(Errno::EBADF)?;
|
||||
let new_fd = mount.dup(fd)?;
|
||||
Ok((new_fd as u64) | (mount_id << 32))
|
||||
}
|
||||
|
||||
fn seek(&self, fd: u64, pos: file_rpc::SeekFrom) -> Result<u64, Errno> {
|
||||
let mount_id = fd >> 32;
|
||||
let fd = fd as u32;
|
||||
let mut mounts = self.mounts.lock();
|
||||
let mount = mounts.get_mut(mount_id as usize).ok_or(Errno::EBADF)?;
|
||||
mount.seek(fd, pos)
|
||||
}
|
||||
}
|
||||
|
||||
impl dir_rpc::Server for Serv {
|
||||
fn next_entry(&self, fd: u64) -> Result<Option<String>, Errno> {
|
||||
let mount_id = fd >> 32;
|
||||
let fd = fd as u32;
|
||||
let mut mounts = self.mounts.lock();
|
||||
let mount = mounts.get_mut(mount_id as usize).ok_or(Errno::EBADF)?;
|
||||
mount.dir_next(fd)
|
||||
}
|
||||
|
||||
fn close(&self, fd: u64) -> Result<(), Errno> {
|
||||
let mount_id = fd >> 32;
|
||||
let fd = fd as u32;
|
||||
let mut mounts = self.mounts.lock();
|
||||
let mount = mounts.get_mut(mount_id as usize).ok_or(Errno::EBADF)?;
|
||||
mount.close(fd)
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let serv = Serv {
|
||||
mounts: Arc::new(Mutex::new(Vec::new())),
|
||||
};
|
||||
fs_rpc::register_server(Box::new(serv.clone()));
|
||||
dir_rpc::register_server(Box::new(serv.clone()));
|
||||
file_rpc::register_server(Box::new(serv));
|
||||
let vfs_pid;
|
||||
loop {
|
||||
if let Some(pid) = syscalls::try_get_registered(0) {
|
||||
vfs_pid = pid;
|
||||
break;
|
||||
}
|
||||
}
|
||||
vfs_rpc::Client::new(vfs_pid).register_fs("tmpfs").unwrap();
|
||||
let syslog_pid;
|
||||
loop {
|
||||
if let Some(pid) = syscalls::try_get_registered(2) {
|
||||
syslog_pid = pid;
|
||||
break;
|
||||
}
|
||||
}
|
||||
syslog_rpc::Client::new(syslog_pid)
|
||||
.send_text_binary_message("tmpfs".to_string(), "Tmpfs initialized".to_string(), 0, [])
|
||||
.unwrap();
|
||||
loop {
|
||||
ipc::process_messages()
|
||||
}
|
||||
}
|
263
src/tempfs.rs
Normal file
263
src/tempfs.rs
Normal file
@ -0,0 +1,263 @@
|
||||
use std::{
|
||||
ffi::OsString,
|
||||
os::mikros::{Errno, FileCreationMode, FileOpenMode},
|
||||
path::Path,
|
||||
};
|
||||
|
||||
struct DirEntry {
|
||||
name: OsString,
|
||||
inode: usize,
|
||||
}
|
||||
|
||||
impl DirEntry {
|
||||
fn new<T: Into<OsString>>(name: T, inode: usize) -> Self {
|
||||
Self {
|
||||
name: name.into(),
|
||||
inode,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
enum Inode {
|
||||
File(Vec<u8>),
|
||||
Directory(Vec<DirEntry>),
|
||||
}
|
||||
|
||||
impl Inode {
|
||||
fn as_directory(&self) -> Option<&Vec<DirEntry>> {
|
||||
if let Self::Directory(v) = self {
|
||||
Some(v)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
fn as_directory_mut(&mut self) -> Option<&mut Vec<DirEntry>> {
|
||||
if let Self::Directory(v) = self {
|
||||
Some(v)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(unused)]
|
||||
fn as_file(&self) -> Option<&Vec<u8>> {
|
||||
if let Self::File(v) = self {
|
||||
Some(v)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
fn as_file_mut(&mut self) -> Option<&mut Vec<u8>> {
|
||||
if let Self::File(v) = self {
|
||||
Some(v)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns `true` if the inode is [`File`].
|
||||
///
|
||||
/// [`File`]: Inode::File
|
||||
#[must_use]
|
||||
fn is_file(&self) -> bool {
|
||||
matches!(self, Self::File(..))
|
||||
}
|
||||
|
||||
/// Returns `true` if the inode is [`Directory`].
|
||||
///
|
||||
/// [`Directory`]: Inode::Directory
|
||||
#[must_use]
|
||||
fn is_directory(&self) -> bool {
|
||||
matches!(self, Self::Directory(..))
|
||||
}
|
||||
}
|
||||
|
||||
struct OpenFile {
|
||||
pos: usize,
|
||||
inode: usize,
|
||||
mode: FileOpenMode,
|
||||
}
|
||||
|
||||
pub struct TempFs {
|
||||
inodes: Vec<Inode>,
|
||||
open_files: Vec<OpenFile>,
|
||||
}
|
||||
|
||||
impl TempFs {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
inodes: vec![Inode::Directory(vec![
|
||||
DirEntry::new(".", 0),
|
||||
DirEntry::new("..", 0),
|
||||
])],
|
||||
open_files: Vec::new(),
|
||||
}
|
||||
}
|
||||
|
||||
fn path_inode<P: AsRef<Path>>(&self, path: P) -> Result<usize, Errno> {
|
||||
let path = path.as_ref();
|
||||
if let Some(parent) = path.parent() {
|
||||
let file_name = path.file_name().ok_or(Errno::EINVAL)?;
|
||||
let dir_inode = self.path_inode(parent)?;
|
||||
let dir_entries = self.inodes[dir_inode].as_directory().unwrap();
|
||||
Ok(dir_entries
|
||||
.iter()
|
||||
.find(|entry| entry.name == file_name)
|
||||
.ok_or(Errno::ENOENT)?
|
||||
.inode)
|
||||
} else {
|
||||
Ok(0)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn open(&mut self, path: &Path, mode: FileOpenMode) -> Result<u32, Errno> {
|
||||
if self.open_files.len() == u32::MAX as usize {
|
||||
return Err(Errno::ENFILE);
|
||||
}
|
||||
let inode = match self.path_inode(path) {
|
||||
Ok(x) => x,
|
||||
Err(Errno::ENOENT) => {
|
||||
if !mode
|
||||
.get_writing_details()
|
||||
.map_or(false, |(_, y)| y != FileCreationMode::NoCreate)
|
||||
{
|
||||
return Err(Errno::ENOENT);
|
||||
}
|
||||
let parent_dir_inode = self.path_inode(path.parent().unwrap())?;
|
||||
self.inodes.push(Inode::File(vec![]));
|
||||
let new_file_inode = self.inodes.len() - 1;
|
||||
let parent_dir = self.inodes[parent_dir_inode].as_directory_mut().unwrap();
|
||||
let file_name = path.file_name().ok_or(Errno::EINVAL)?;
|
||||
parent_dir.push(DirEntry { name: file_name.to_owned(), inode: new_file_inode });
|
||||
new_file_inode
|
||||
}
|
||||
Err(e) => return Err(e),
|
||||
};
|
||||
if !self.inodes[inode].is_file() {
|
||||
return Err(Errno::EISDIR);
|
||||
}
|
||||
if let Some((wr_mode, _)) = mode.get_writing_details() {
|
||||
if wr_mode.truncate {
|
||||
self.inodes[inode].as_file_mut().unwrap().clear();
|
||||
}
|
||||
}
|
||||
let file = OpenFile {
|
||||
pos: 0,
|
||||
inode,
|
||||
mode,
|
||||
};
|
||||
self.open_files.push(file);
|
||||
Ok((self.open_files.len() - 1) as u32)
|
||||
}
|
||||
|
||||
pub fn open_dir(&mut self, path: &Path) -> Result<u32, Errno> {
|
||||
if self.open_files.len() == u32::MAX as usize {
|
||||
return Err(Errno::ENFILE);
|
||||
}
|
||||
let inode = self.path_inode(path)?;
|
||||
if !self.inodes[inode].is_directory() {
|
||||
return Err(Errno::ENOTDIR);
|
||||
}
|
||||
let file = OpenFile {
|
||||
pos: 0,
|
||||
inode,
|
||||
mode: FileOpenMode::Read,
|
||||
};
|
||||
self.open_files.push(file);
|
||||
Ok((self.open_files.len() - 1) as u32)
|
||||
}
|
||||
|
||||
pub fn read(&mut self, fd: u32, len: usize) -> Result<Vec<u8>, Errno> {
|
||||
let file = self.open_files.get_mut(fd as usize).ok_or(Errno::EBADF)?;
|
||||
let Inode::File(ref data) = self.inodes[file.inode] else {
|
||||
return Err(Errno::EISDIR);
|
||||
};
|
||||
if !file.mode.readable() {
|
||||
return Err(Errno::EACCES);
|
||||
}
|
||||
let read_len = usize::min(data.len() - file.pos, len);
|
||||
let data = data[file.pos..][..read_len].to_vec();
|
||||
file.pos += read_len;
|
||||
Ok(data)
|
||||
}
|
||||
|
||||
pub fn write(&mut self, fd: u32, data: &[u8]) -> Result<(), Errno> {
|
||||
let file = self.open_files.get_mut(fd as usize).ok_or(Errno::EBADF)?;
|
||||
let Inode::File(ref mut file_data) = self.inodes[file.inode] else {
|
||||
return Err(Errno::EISDIR);
|
||||
};
|
||||
let Some((wr_mode, _)) = file.mode.get_writing_details() else {
|
||||
return Err(Errno::EACCES);
|
||||
};
|
||||
if wr_mode.append {
|
||||
file.pos = file_data.len();
|
||||
}
|
||||
let write_end = file.pos + data.len() - 1;
|
||||
if write_end >= file_data.len() {
|
||||
file_data.resize(write_end + 1, 0);
|
||||
}
|
||||
file_data[file.pos..][..data.len()].copy_from_slice(data);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn close(&mut self, _fd: u32) -> Result<(), Errno> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn size(&self, fd: u32) -> Result<u64, Errno> {
|
||||
let file = self.open_files.get(fd as usize).ok_or(Errno::EBADF)?;
|
||||
let Inode::File(ref data) = self.inodes[file.inode] else {
|
||||
return Err(Errno::EISDIR);
|
||||
};
|
||||
Ok(data.len() as u64)
|
||||
}
|
||||
|
||||
pub fn dup(&mut self, fd: u32) -> Result<u32, Errno> {
|
||||
Ok(fd)
|
||||
}
|
||||
|
||||
pub fn seek(&mut self, fd: u32, pos: file_rpc::SeekFrom) -> Result<u64, Errno> {
|
||||
let file = self.open_files.get_mut(fd as usize).ok_or(Errno::EBADF)?;
|
||||
let Inode::File(ref data) = self.inodes[file.inode] else {
|
||||
return Err(Errno::EISDIR);
|
||||
};
|
||||
match pos {
|
||||
file_rpc::SeekFrom::Start(offset) => {
|
||||
file.pos = offset as usize;
|
||||
}
|
||||
file_rpc::SeekFrom::End(offset) => {
|
||||
if offset <= 0 {
|
||||
file.pos = data.len() - (-offset) as usize;
|
||||
}
|
||||
}
|
||||
file_rpc::SeekFrom::Current(offset) => {
|
||||
if offset > 0 {
|
||||
file.pos = usize::min(file.pos + offset as usize, data.len());
|
||||
} else {
|
||||
let offset = (-offset) as usize;
|
||||
if offset > file.pos {
|
||||
file.pos = 0;
|
||||
} else {
|
||||
file.pos -= offset;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(file.pos as u64)
|
||||
}
|
||||
|
||||
pub fn dir_next(&mut self, fd: u32) -> Result<Option<String>, Errno> {
|
||||
let dir = self.open_files.get_mut(fd as usize).ok_or(Errno::EBADF)?;
|
||||
let Inode::Directory(ref entries) = self.inodes[dir.inode] else {
|
||||
return Err(Errno::ENOTDIR);
|
||||
};
|
||||
if dir.pos == entries.len() {
|
||||
Ok(None)
|
||||
} else {
|
||||
let name = entries[dir.pos].name.clone();
|
||||
dir.pos += 1;
|
||||
Ok(Some(name.to_string_lossy().into_owned()))
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user