diff --git a/Cargo.lock b/Cargo.lock index 9a6e0121a..58d688159 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -19,9 +19,9 @@ dependencies = [ [[package]] name = "anstream" -version = "0.6.4" +version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ab91ebe16eb252986481c5b62f6098f3b698a45e34b5b98200cf20dd2484a44" +checksum = "d664a92ecae85fd0a7392615844904654d1d5f5514837f471ddef4a057aba1b6" dependencies = [ "anstyle", "anstyle-parse", @@ -39,27 +39,27 @@ checksum = "7079075b41f533b8c61d2a4d073c4676e1f8b249ff94a393b0595db304e0dd87" [[package]] name = "anstyle-parse" -version = "0.2.2" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "317b9a89c1868f5ea6ff1d9539a69f45dffc21ce321ac1fd1160dfa48c8e2140" +checksum = "c75ac65da39e5fe5ab759307499ddad880d724eed2f6ce5b5e8a26f4f387928c" dependencies = [ "utf8parse", ] [[package]] name = "anstyle-query" -version = "1.0.0" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ca11d4be1bab0c8bc8734a9aa7bf4ee8316d462a08c6ac5052f888fef5b494b" +checksum = "e28923312444cdd728e4738b3f9c9cac739500909bb3d3c94b43551b16517648" dependencies = [ "windows-sys", ] [[package]] name = "anstyle-wincon" -version = "3.0.1" +version = "3.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0699d10d2f4d628a98ee7b57b289abbc98ff3bad977cb3152709d4bf2330628" +checksum = "1cd54b81ec8d6180e24654d0b371ad22fc3dd083b6ff8ba325b72e00c87660a7" dependencies = [ "anstyle", "windows-sys", @@ -185,14 +185,14 @@ dependencies = [ "js-sys", "num-traits", "wasm-bindgen", - "windows-targets", + "windows-targets 0.48.5", ] [[package]] name = "clap" -version = "4.4.8" +version = "4.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2275f18819641850fa26c89acc84d465c1bf91ce57bc2748b28c420473352f64" +checksum = "bfaff671f6b22ca62406885ece523383b9b64022e341e53e009a62ebc47a45f2" dependencies = [ "clap_builder", "clap_derive", @@ -200,9 +200,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.4.8" +version = "4.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07cdf1b148b25c1e1f7a42225e30a0d99a615cd4637eae7365548dd4529b95bc" +checksum = "a216b506622bb1d316cd51328dce24e07bdff4a6128a47c7e7fad11878d5adbb" dependencies = [ "anstream", "anstyle", @@ -242,9 +242,9 @@ checksum = "f7144d30dcf0fafbce74250a3963025d8d52177934239851c917d29f1df280c2" [[package]] name = "core-foundation-sys" -version = "0.8.4" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" +checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" [[package]] name = "coreutils" @@ -301,9 +301,9 @@ dependencies = [ [[package]] name = "deranged" -version = "0.3.9" +version = "0.3.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f32d04922c60427da6f9fef14d042d9edddef64cb9d4ce0d64d0685fbeb1fd3" +checksum = "8eb30d70a07a3b04884d2677f06bec33509dc67ca60d92949e5535352d3191dc" dependencies = [ "powerfmt", ] @@ -322,9 +322,9 @@ checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" [[package]] name = "elf" -version = "0.7.3" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f6e7d85896690fe195447717af8eceae0593ac2196fd42fe88c184e904406ce" +checksum = "4445909572dbd556c457c849c4ca58623d84b27c8fff1e74b0b4227d8b90d17b" [[package]] name = "fbtest" @@ -745,6 +745,8 @@ dependencies = [ "libm", "lock_api", "sample-elf", + "serde", + "serde_json", "snafu", "spin", "time", @@ -945,20 +947,26 @@ dependencies = [ "either", ] +[[package]] +name = "itoa" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" + [[package]] name = "js-sys" -version = "0.3.65" +version = "0.3.66" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54c0c35952f67de54bb584e9fd912b3023117cbafc0a77d8f3dee1fb5f572fe8" +checksum = "cee9c64da59eae3b50095c18d3e74f8b73c0b86d2792824ff01bbce68ba229ca" dependencies = [ "wasm-bindgen", ] [[package]] name = "libc" -version = "0.2.150" +version = "0.2.151" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89d92a4743f9a61002fae18374ed11e7973f530cb3a3255fb354818118b2203c" +checksum = "302d7ab3130588088d277783b1e2d2e10c9e9e4a16dd9050e6ec93fb3e7048f4" [[package]] name = "libm" @@ -1018,9 +1026,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.18.0" +version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" [[package]] name = "paste" @@ -1059,9 +1067,9 @@ checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" [[package]] name = "proc-macro2" -version = "1.0.69" +version = "1.0.70" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" +checksum = "39278fbbf5fb4f646ce651690877f89d1c5811a3d4acb27700c1cb3cdb78fd3b" dependencies = [ "unicode-ident", ] @@ -1131,6 +1139,12 @@ version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" +[[package]] +name = "ryu" +version = "1.0.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c" + [[package]] name = "sample-elf" version = "0.1.0" @@ -1144,6 +1158,37 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" +[[package]] +name = "serde" +version = "1.0.193" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25dd9975e68d0cb5aa1120c288333fc98731bd1dd12f561e468ea4728c042b89" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.193" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43576ca501357b9b071ac53cdc7da8ef0cbd9493d8df094cd821777ea6e894d3" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.39", +] + +[[package]] +name = "serde_json" +version = "1.0.108" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d1c7e3eac408d115102c4c24ad393e0821bb3a5df4d506a80f85f7a742a526b" +dependencies = [ + "itoa", + "ryu", + "serde", +] + [[package]] name = "smallvec" version = "1.11.2" @@ -1263,9 +1308,9 @@ checksum = "9eaac9f9d9b7ae00cdd43e21b15e58ccacd903e6d29131d7536765a61969d25e" [[package]] name = "wasm-bindgen" -version = "0.2.88" +version = "0.2.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7daec296f25a1bae309c0cd5c29c4b260e510e6d813c286b19eaadf409d40fce" +checksum = "0ed0d4f68a3015cc185aff4db9506a015f4b96f95303897bfa23f846db54064e" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -1273,9 +1318,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.88" +version = "0.2.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e397f4664c0e4e428e8313a469aaa58310d302159845980fd23b0f22a847f217" +checksum = "1b56f625e64f3a1084ded111c4d5f477df9f8c92df113852fa5a374dbda78826" dependencies = [ "bumpalo", "log", @@ -1288,9 +1333,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.88" +version = "0.2.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5961017b3b08ad5f3fe39f1e79877f8ee7c23c5e5fd5eb80de95abc41f1f16b2" +checksum = "0162dbf37223cd2afce98f3d0785506dcb8d266223983e4b5b525859e6e182b2" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -1298,9 +1343,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.88" +version = "0.2.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5353b8dab669f5e10f5bd76df26a9360c748f054f862ff5f3f8aae0c7fb3907" +checksum = "f0eb82fcb7930ae6219a7ecfd55b217f5f0893484b7a13022ebb2b2bf20b5283" dependencies = [ "proc-macro2", "quote", @@ -1311,9 +1356,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.88" +version = "0.2.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d046c5d029ba91a1ed14da14dca44b68bf2f124cfbaf741c54151fdb3e0750b" +checksum = "7ab9b36309365056cd639da3134bf87fa8f3d86008abf99e612384a6eecd459f" [[package]] name = "windows-core" @@ -1321,16 +1366,16 @@ version = "0.51.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f1f8cf84f35d2db49a46868f947758c7a1138116f7fac3bc844f43ade1292e64" dependencies = [ - "windows-targets", + "windows-targets 0.48.5", ] [[package]] name = "windows-sys" -version = "0.48.0" +version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets", + "windows-targets 0.52.0", ] [[package]] @@ -1339,13 +1384,28 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", +] + +[[package]] +name = "windows-targets" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd" +dependencies = [ + "windows_aarch64_gnullvm 0.52.0", + "windows_aarch64_msvc 0.52.0", + "windows_i686_gnu 0.52.0", + "windows_i686_msvc 0.52.0", + "windows_x86_64_gnu 0.52.0", + "windows_x86_64_gnullvm 0.52.0", + "windows_x86_64_msvc 0.52.0", ] [[package]] @@ -1354,42 +1414,84 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea" + [[package]] name = "windows_aarch64_msvc" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef" + [[package]] name = "windows_i686_gnu" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" +[[package]] +name = "windows_i686_gnu" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313" + [[package]] name = "windows_i686_msvc" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" +[[package]] +name = "windows_i686_msvc" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a" + [[package]] name = "windows_x86_64_gnu" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd" + [[package]] name = "windows_x86_64_gnullvm" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e" + [[package]] name = "windows_x86_64_msvc" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" + [[package]] name = "x86" version = "0.52.0" diff --git a/crates/kshell/Cargo.toml b/crates/kshell/Cargo.toml index 9f99baeb1..f4c59295e 100644 --- a/crates/kshell/Cargo.toml +++ b/crates/kshell/Cargo.toml @@ -19,6 +19,9 @@ lock_api.workspace = true glam = { version = "0.24", default-features = false, features = ["libm"] } itertools = { version = "0.11", default-features = false } +serde = { version = "1.0", default-features = false, features = ["derive"] } +serde_json = { version = "1.0", default-features = false, features = ["alloc"] } + hyperion-arch.path = "../arch" hyperion-color.path = "../color" hyperion-driver-acpi.path = "../driver-acpi" diff --git a/crates/kshell/src/lib.rs b/crates/kshell/src/lib.rs index 04c725752..ad7e2e136 100644 --- a/crates/kshell/src/lib.rs +++ b/crates/kshell/src/lib.rs @@ -46,7 +46,7 @@ macro_rules! load_elf_from { // pub async fn kshell() { - hyperion_futures::executor::spawn(spinner()); + // hyperion_futures::executor::spawn(spinner()); // TODO: initrd @@ -84,22 +84,22 @@ pub async fn kshell() { term.flush(); } -async fn spinner() { - let mut ticks = ticks(Duration::milliseconds(50)); - let mut rng = hyperion_random::next_fast_rng(); - - while ticks.next().await.is_some() { - let Some(fbo) = Framebuffer::get() else { - continue; - }; - let mut fbo = fbo.lock(); - - let (r, g, b) = rng.gen(); - let x = fbo.width - 20; - let y = fbo.height - 20; - fbo.fill(x, y, 10, 10, Color::new(r, g, b)); - } -} +// async fn spinner() { +// let mut ticks = ticks(Duration::milliseconds(50)); +// let mut rng = hyperion_random::next_fast_rng(); + +// while ticks.next().await.is_some() { +// let Some(fbo) = Framebuffer::get() else { +// continue; +// }; +// let mut fbo = fbo.lock(); + +// let (r, g, b) = rng.gen(); +// let x = fbo.width - 20; +// let y = fbo.height - 20; +// fbo.fill(x, y, 10, 10, Color::new(r, g, b)); +// } +// } // diff --git a/crates/kshell/src/shell.rs b/crates/kshell/src/shell.rs index 43eb73d68..3e5fd95d6 100644 --- a/crates/kshell/src/shell.rs +++ b/crates/kshell/src/shell.rs @@ -5,7 +5,7 @@ use alloc::{ sync::Arc, vec::Vec, }; -use core::{fmt::Write, sync::atomic::Ordering}; +use core::{fmt::Write, sync::atomic::Ordering, time::Duration}; use futures_util::stream::select; use hyperion_color::Color; @@ -469,8 +469,8 @@ impl Shell { let (stdin_tx, stdin_rx) = channel(); let (stdout_tx, stdout_rx) = channel(); - // let (stderr_tx, stderr_rx) = pipe(); - let stderr_tx = stdout_tx.clone(); + let (stderr_tx, stderr_rx) = channel(); + // let stderr_tx = stdout_tx.clone(); let (o_tx, o_rx) = hyperion_futures::mpmc::channel(); @@ -492,6 +492,20 @@ impl Shell { o_tx_2.send(None); }); + spawn(move || loop { + let mut buf = [0; 128]; + let Ok(len) = stderr_rx.recv_slice(&mut buf) else { + debug!("end of stream"); + break; + }; + let Ok(str) = core::str::from_utf8(&buf[..len]) else { + debug!("invalid utf8"); + break; + }; + + print!("{str}"); + }); + schedule(move || { let name = name.as_ref(); hyperion_scheduler::rename(name); @@ -526,11 +540,38 @@ impl Shell { } }); + // hyperion_futures::executor::spawn(async move { + // while let Some(ev) = KeyboardEvents.next().await { + // hyperion_log::debug!("GOT {ev:?}"); + + // let mut str = [0; 4]; + + // if let Some(unicode) = ev.unicode { + // let str = unicode.encode_utf8(&mut str); + + // // TODO: buffering + // if let Err(err) = stdin_tx.send_slice(str.as_bytes()) { + // hyperion_log::debug!("STDIN send err {err:?}"); + // break; + // } + // } + // } + // }); + + // loop { + // hyperion_log::debug!("sleep"); + // hyperion_futures::timer::sleep(time::Duration::SECOND).await; + // } + let mut events = select(KeyboardEvents.map(Ok), o_rx.race_stream().map(Err)); let mut l_ctrl_held = false; loop { - match events.next().await { + // hyperion_log::debug!("Waiting for events ..."); + let ev = events.next().await; + // hyperion_log::debug!("Event {ev:?}"); + + match ev { Some(Ok(KeyboardEvent { state, keycode, @@ -550,23 +591,47 @@ impl Shell { break; } - if let Some(unicode) = unicode { - _ = write!(self.term, "{unicode}"); - self.term.flush(); + // if let Some(unicode) = unicode { + // // _ = write!(self.term, "{unicode}"); + // // self.term.flush(); - let mut str = [0; 4]; + // let mut str = [0; 4]; - let str = unicode.encode_utf8(&mut str); + // let str = unicode.encode_utf8(&mut str); - // TODO: buffering - if stdin_tx.send_slice(str.as_bytes()).is_err() { - break; - } + // // TODO: buffering + // if let Err(err) = stdin_tx.send_slice(str.as_bytes()) { + // break; + // } + // } + + #[derive(serde::Serialize, serde::Deserialize)] + struct KeyboardEventSer { + // pub scancode: u8, + state: u8, + keycode: u8, + unicode: Option, + } + + let ev = serde_json::to_string(&KeyboardEventSer { + state: state as u8, + keycode: keycode as u8, + unicode, + }) + .unwrap(); + // hyperion_log::debug!("sending {ev}"); + if let Err(_) = stdin_tx.send_slice(ev.as_bytes()) { + // hyperion_log::debug!("stdin closed"); + break; + } + if let Err(_) = stdin_tx.send_slice("\n".as_bytes()) { + // hyperion_log::debug!("stdin closed"); + break; } } Some(Err(Some(s))) => { - _ = write!(self.term, "{s}"); - self.term.flush(); + // _ = write!(self.term, "{s}"); + // self.term.flush(); } Some(Err(None)) => { // _ = write!(self.term, "got EOI"); @@ -577,7 +642,9 @@ impl Shell { } } - stdin_tx.close(); + hyperion_log::debug!("done"); + + // stdin_tx.close(); Ok(()) } diff --git a/crates/libstd/src/fs.rs b/crates/libstd/src/fs.rs index bc3984d53..46dee83a3 100644 --- a/crates/libstd/src/fs.rs +++ b/crates/libstd/src/fs.rs @@ -3,13 +3,13 @@ use core::mem::ManuallyDrop; use core_alloc::string::String; use hyperion_syscall::{ close, - err::Result, + err::{Error, Result}, fs::{FileDesc, FileOpenFlags, Metadata}, metadata, open, open_dir, read, write, }; use spin::{Mutex, MutexGuard}; -use crate::io::{BufReader, BufWriter, ConstBufReader}; +use crate::io::{self, BufReader, BufWriter, ConstBufReader}; // @@ -99,6 +99,7 @@ impl Dir { // +#[derive(Debug)] pub struct DirEntry<'a> { pub is_dir: bool, // TODO: mode flags later pub size: usize, @@ -107,8 +108,10 @@ pub struct DirEntry<'a> { // +#[derive(Debug)] pub struct File { desc: FileDesc, + closed: bool, } impl File { @@ -118,7 +121,10 @@ impl File { /// /// this transfers the ownership of `desc` and will automatically close the file when dropped pub const unsafe fn new(desc: FileDesc) -> Self { - Self { desc } + Self { + desc, + closed: false, + } } /// # Safety @@ -132,7 +138,10 @@ impl File { /// /// file i/o won't be automatically synchronized pub const unsafe fn clone(&self) -> Self { - Self { desc: self.desc } + Self { + desc: self.desc, + closed: self.closed, + } } pub const fn as_desc(&self) -> FileDesc { @@ -143,15 +152,12 @@ impl File { OpenOptions::new().read(true).write(true).open(path) } - pub fn read(&self, buf: &mut [u8]) -> Result { - read(self.desc, buf) - } - - pub fn write(&self, buf: &[u8]) -> Result { - write(self.desc, buf) - } + pub fn close(&mut self) -> Result<()> { + if self.closed { + return Err(Error::CLOSED); + } + self.closed = true; - pub fn close(&self) -> Result<()> { close(self.desc) } @@ -162,9 +168,31 @@ impl File { } } +impl io::Read for File { + fn read(&mut self, buf: &mut [u8]) -> Result { + if self.closed { + return Err(Error::CLOSED); + } + read(self.desc, buf) + } +} + +impl io::Write for File { + fn write(&mut self, buf: &[u8]) -> Result { + if self.closed { + return Err(Error::CLOSED); + } + write(self.desc, buf) + } + + fn flush(&mut self) -> Result<()> { + Ok(()) + } +} + impl Drop for File { fn drop(&mut self) { - self.close().expect("failed to close the file"); + close(self.desc).expect("failed to close the file"); } } diff --git a/crates/libstd/src/io.rs b/crates/libstd/src/io.rs index 23a782b8e..b5d9eaaf7 100644 --- a/crates/libstd/src/io.rs +++ b/crates/libstd/src/io.rs @@ -9,11 +9,26 @@ use crate::fs::File; pub trait Read { fn read(&mut self, buf: &mut [u8]) -> Result; -} -impl Read for File { - fn read(&mut self, buf: &mut [u8]) -> Result { - File::read(self, buf) + fn read_exact(&mut self, mut buf: &mut [u8], bytes_read: &mut usize) -> Result<()> { + while !buf.is_empty() { + match self.read(buf) { + Ok(0) => break, + Ok(n) => { + let tmp = buf; + buf = &mut tmp[n..]; + *bytes_read += n; + } + Err(Error::INTERRUPTED) => {} + Err(err) => return Err(err), + } + } + + if !buf.is_empty() { + Err(Error::UNEXPECTED_EOF) + } else { + Ok(()) + } } } @@ -28,17 +43,22 @@ impl Read for &mut T { pub trait Write { fn write(&mut self, buf: &[u8]) -> Result; - fn flush(&mut self) -> Result<()>; -} - -impl Write for File { - fn write(&mut self, buf: &[u8]) -> Result { - File::write(self, buf) - } - - fn flush(&mut self) -> Result<()> { + fn write_exact(&mut self, mut buf: &[u8], bytes_written: &mut usize) -> Result<()> { + while !buf.is_empty() { + match self.write(buf) { + Ok(0) => return Err(Error::WRITE_ZERO), + Ok(n) => { + buf = &buf[n..]; + *bytes_written += n; + } + Err(Error::INTERRUPTED) => {} + Err(err) => return Err(err), + } + } Ok(()) } + + fn flush(&mut self) -> Result<()>; } impl Write for &mut T { diff --git a/crates/libstd/src/lib.rs b/crates/libstd/src/lib.rs index f09b52311..459958653 100644 --- a/crates/libstd/src/lib.rs +++ b/crates/libstd/src/lib.rs @@ -87,6 +87,6 @@ pub fn _eprint(args: fmt::Arguments) { #[panic_handler] fn panic_handler(info: &core::panic::PanicInfo) -> ! { - println!("{info}"); + eprintln!("{info}"); exit(-1); } diff --git a/crates/libstd/src/process.rs b/crates/libstd/src/process.rs index 9ace3c3f5..81f90f781 100644 --- a/crates/libstd/src/process.rs +++ b/crates/libstd/src/process.rs @@ -56,7 +56,7 @@ impl ExitCode { pub const FAILURE: Self = Self(-1); - pub(crate) fn from_i32(i: i32) -> Self { + pub fn from_i32(i: i32) -> Self { Self(i) } diff --git a/crates/vfs/src/device.rs b/crates/vfs/src/device.rs index f2a51d7cb..17801a99b 100644 --- a/crates/vfs/src/device.rs +++ b/crates/vfs/src/device.rs @@ -100,7 +100,7 @@ impl FileDevice for [u8] { .ok_or(IoError::UnexpectedEOF)? .min(buf.len()); - buf[..len].copy_from_slice(&self[offset..offset + len]); + buf[..len].copy_from_slice(&self[offset..][..len]); Ok(len) } @@ -112,7 +112,7 @@ impl FileDevice for [u8] { .ok_or(IoError::UnexpectedEOF)? .min(buf.len()); - self[offset..offset + len].copy_from_slice(&buf[..len]); + self[offset..][..len].copy_from_slice(&buf[..len]); Ok(len) } diff --git a/userspace/coreutils/src/cat.rs b/userspace/coreutils/src/cat.rs index 84f01104c..a6030c40f 100644 --- a/userspace/coreutils/src/cat.rs +++ b/userspace/coreutils/src/cat.rs @@ -1,7 +1,7 @@ use core::fmt; use anyhow::{anyhow, Result}; -use libstd::{fs::File, print, println}; +use libstd::{fs::File, io::Read, print, println}; // @@ -10,7 +10,7 @@ pub fn cmd<'a>(mut args: impl Iterator) -> Result<()> { .next() .ok_or_else(|| anyhow!("expected at least one argument"))?; - let file = File::open(a1).map_err(|err| anyhow!("`{a1}`: {err}"))?; + let mut file = File::open(a1).map_err(|err| anyhow!("`{a1}`: {err}"))?; let mut buf = [0u8; 512]; loop { diff --git a/userspace/sample-elf/src/main.rs b/userspace/sample-elf/src/main.rs index 45e88ac37..032e9249a 100644 --- a/userspace/sample-elf/src/main.rs +++ b/userspace/sample-elf/src/main.rs @@ -10,7 +10,7 @@ use core::str::from_utf8; use libstd::{ fs::{File, OpenOptions, Stdin, STDOUT}, - io::{BufReader, Write}, + io::{BufReader, Read, Write}, println, sync::Mutex, sys::{ @@ -50,7 +50,7 @@ fn handle_client(i: usize, conn: SocketDesc) -> Result<()> { let len = recv(conn, &mut buf, 0)?; assert_eq!(&buf[..len], b"ack"); - let file = OpenOptions::new() + let mut file = OpenOptions::new() .read(true) .create(false) .open(format!("/tmp/{msg}"))?; @@ -78,7 +78,7 @@ fn run_client() -> Result<()> { let msg = from_utf8(utf8).unwrap(); println!("got `{msg:?}`"); - let file = OpenOptions::new() + let mut file = OpenOptions::new() .write(true) .create(true) .open(format!("/tmp/{msg}"))?;