From 43acdb9e136c48a93b0d0b00b52b34c4a783f3d7 Mon Sep 17 00:00:00 2001 From: Mark Poliakov Date: Wed, 26 Feb 2025 11:52:05 +0200 Subject: [PATCH] libc/colors: non-blocking local socket + fixed string bugs in libc --- kernel/libk/src/vfs/socket.rs | 2 +- lib/runtime/src/io/mod.rs | 4 + test.c | 16 ++-- userspace/colors/src/input.rs | 2 + userspace/colors/src/main.rs | 79 +++++++++++++------ userspace/dyn-loader/src/main.rs | 16 +++- userspace/dyn-loader/src/object.rs | 10 ++- userspace/dyn-loader/src/relocation/x86_64.rs | 2 +- userspace/etc/profile | 2 +- userspace/etc/test.S | 4 +- userspace/etc/test.c | 9 ++- userspace/etc/test.cpp | 6 ++ userspace/etc/test.sh | 3 + userspace/lib/cross/src/net.rs | 4 + userspace/lib/cross/src/sys/mod.rs | 2 + .../lib/cross/src/sys/yggdrasil/socket.rs | 5 ++ .../libcolors/src/application/connection.rs | 16 ++++ .../lib/libcolors/src/application/mod.rs | 20 ++++- .../lib/libcolors/src/application/window.rs | 20 ++++- userspace/lib/uipc/src/lib.rs | 14 ++++ userspace/lib/ygglibc/include/bits/sys/wait.h | 2 + userspace/lib/ygglibc/src/cxxabi.rs | 15 ++-- userspace/lib/ygglibc/src/error.rs | 1 + .../lib/ygglibc/src/headers/fcntl/mod.rs | 17 ++-- .../lib/ygglibc/src/headers/pthread/mutex.rs | 2 +- .../lib/ygglibc/src/headers/spawn/mod.rs | 23 ++++-- .../ygglibc/src/headers/stdio/printf/mod.rs | 7 ++ .../lib/ygglibc/src/headers/stdlib/process.rs | 6 +- .../lib/ygglibc/src/headers/string/str.rs | 20 ++++- .../lib/ygglibc/src/headers/strings/mod.rs | 12 ++- .../lib/ygglibc/src/headers/sys_mman/mod.rs | 20 +++-- .../src/headers/sys_resource/cbindgen.toml | 2 +- .../ygglibc/src/headers/sys_resource/mod.rs | 2 + .../lib/ygglibc/src/headers/sys_stat/mod.rs | 15 ++-- .../src/headers/sys_wait/cbindgen.toml | 1 + .../lib/ygglibc/src/headers/sys_wait/mod.rs | 79 ++++++++++++++++++- userspace/lib/ygglibc/src/io/mod.rs | 7 +- userspace/lib/ygglibc/src/lib.rs | 11 +++ userspace/lib/ygglibc/src/thread/mod.rs | 42 +++++++++- userspace/shell/src/syntax/lex.rs | 2 +- userspace/sysutils/src/tst.rs | 20 ++--- userspace/term/src/main.rs | 1 + xtask/src/build/c.rs | 31 +++++--- 43 files changed, 459 insertions(+), 115 deletions(-) create mode 100644 userspace/etc/test.cpp diff --git a/kernel/libk/src/vfs/socket.rs b/kernel/libk/src/vfs/socket.rs index b9be493e..2149d1d6 100644 --- a/kernel/libk/src/vfs/socket.rs +++ b/kernel/libk/src/vfs/socket.rs @@ -129,7 +129,7 @@ impl SocketWrapper { non_blocking: bool, ) -> Result { if non_blocking { - todo!() + self.inner.clone().send_nonblocking(message) } else { let timeout = self.options.read().send_timeout; block!(self.inner.clone().send_message(message, timeout).await)? diff --git a/lib/runtime/src/io/mod.rs b/lib/runtime/src/io/mod.rs index 98e1e079..b80e6492 100644 --- a/lib/runtime/src/io/mod.rs +++ b/lib/runtime/src/io/mod.rs @@ -102,3 +102,7 @@ pub fn set_file_option_with<'de, T: OptionValue<'de>>( let len = T::store(value, buffer)?; unsafe { crate::sys::set_file_option(fd, T::VARIANT.into(), &buffer[..len]) } } + +pub fn set_nonblocking(fd: RawFd, nonblocking: bool) -> Result<(), Error> { + set_file_option::(fd, &nonblocking) +} diff --git a/test.c b/test.c index 6d83ec29..511564fd 100644 --- a/test.c +++ b/test.c @@ -1,16 +1,12 @@ +#include #include #include int main(int argc, char **argv) { - struct Dl_info dl0, dl1; - - dladdr(main, &dl0); - dladdr(printf, &dl1); - printf("%s: %p\n", dl1.dli_sname, dl1.dli_saddr); - printf("%s @ %p\n", dl1.dli_fname, dl1.dli_fbase); - - printf("%s: %p\n", dl0.dli_sname, dl0.dli_saddr); - printf("%s @ %p\n", dl0.dli_fname, dl0.dli_fbase); - + char buffer[9] = {1, 2, 3, 4, 5, 6, 7, 8, 9}; + strncpy(buffer, "abcdefghijkl", sizeof(buffer)); + for (int i = 0; i < sizeof(buffer); ++i) { + printf("[%d] 0x%hhx\n", i, buffer[i]); + } return 0; } diff --git a/userspace/colors/src/input.rs b/userspace/colors/src/input.rs index 6112f948..ea1fc6b6 100644 --- a/userspace/colors/src/input.rs +++ b/userspace/colors/src/input.rs @@ -43,6 +43,8 @@ impl InputState { b'.' => b'>', b'`' => b'~', b'\\' => b'|', + b'[' => b'{', + b']' => b'}', _ => ch, } } diff --git a/userspace/colors/src/main.rs b/userspace/colors/src/main.rs index fe805354..81f871bc 100644 --- a/userspace/colors/src/main.rs +++ b/userspace/colors/src/main.rs @@ -11,7 +11,7 @@ use std::{ use cross::mem::SharedMemory; use input::InputState; use libcolors::{ - event::{EventData, KeyModifiers, KeyboardKeyEvent, WindowEvent, WindowInfo}, + event::{EventData, KeyEvent, KeyModifiers, KeyboardKeyEvent, WindowEvent, WindowInfo}, input::Key, message::{ClientMessage, CreateWindowInfo, WindowType}, }; @@ -67,7 +67,7 @@ impl<'a> Server<'a> { surface: &mut DisplaySurface, tx: &mut ServerSender, peer: &PeerAddress, - info: CreateWindowInfo + info: CreateWindowInfo, ) -> Result<(WindowInfo, RawFd), Error> { let wid = self.last_window_id; self.last_window_id += 1; @@ -152,17 +152,22 @@ impl<'a> Server<'a> { } } - fn move_window(&mut self, surface: &mut DisplaySurface, tx: &mut ServerSender, direction: Direction) { + fn move_window( + &mut self, + surface: &mut DisplaySurface, + tx: &mut ServerSender, + direction: Direction, + ) { if self.workspace.move_window(direction) { surface.fill(self.background); self.flush_dirty_frames(tx); self.workspace.all_windows().for_each(|(wid, _)| { - if let Some(window) = self.windows.get(&wid) { - tx.send_event( - EventData::WindowEvent(wid, WindowEvent::RedrawRequested), - &window.peer, - ); - } + if let Some(window) = self.windows.get(&wid) { + tx.send_event( + EventData::WindowEvent(wid, WindowEvent::RedrawRequested), + &window.peer, + ); + } }); } } @@ -192,7 +197,8 @@ impl<'a> Server<'a> { impl WindowServer for Server<'_> { fn handle_initial(&mut self, mut surface: DisplaySurface) { - self.workspace.resize(surface.width() as u32, surface.height() as u32); + self.workspace + .resize(surface.width() as u32, surface.height() as u32); surface.fill(self.background); surface.present(); @@ -285,9 +291,9 @@ impl WindowServer for Server<'_> { ) { self.input_state.update(event.key, event.state); - if event.state { - let input = self.input_state.make_input(event.key); + let input = self.input_state.make_input(event.key); + if event.state { // Non-window keys #[allow(clippy::single_match)] match (input.modifiers, input.key) { @@ -299,11 +305,6 @@ impl WindowServer for Server<'_> { _ => (), } - let focus = self.workspace.focused_window().and_then(|wid| { - let window = self.windows.get(&wid)?; - Some((wid, window)) - }); - match (input.modifiers, input.key) { (KeyModifiers::ALT, Key::Char(b'l')) => { self.move_focus(tx, Direction::Right); @@ -344,14 +345,6 @@ impl WindowServer for Server<'_> { _ => (), } - if let Some((wid, window)) = focus { - // Deliver event to the window - tx.send_event( - EventData::WindowEvent(wid, WindowEvent::KeyInput(input)), - &window.peer, - ); - } - // // Window keys // if let Some((row, col)) = self.focused_frame { // let row_len = self.rows[row].frames.len(); @@ -361,6 +354,42 @@ impl WindowServer for Server<'_> { // self.focused_frame = None; // } } + + let focus = self.workspace.focused_window().and_then(|wid| { + let window = self.windows.get(&wid)?; + Some((wid, window)) + }); + if let Some((wid, window)) = focus { + if event.state { + tx.send_event( + EventData::WindowEvent( + wid, + WindowEvent::KeyPressed(KeyEvent { + key: event.key, + modifiers: input.modifiers, + }), + ), + &window.peer, + ); + + // Deliver event to the window + tx.send_event( + EventData::WindowEvent(wid, WindowEvent::KeyInput(input)), + &window.peer, + ); + } else { + tx.send_event( + EventData::WindowEvent( + wid, + WindowEvent::KeyReleased(KeyEvent { + key: event.key, + modifiers: input.modifiers, + }), + ), + &window.peer, + ); + } + } } } diff --git a/userspace/dyn-loader/src/main.rs b/userspace/dyn-loader/src/main.rs index 196d3d9b..89ee6aa6 100644 --- a/userspace/dyn-loader/src/main.rs +++ b/userspace/dyn-loader/src/main.rs @@ -8,7 +8,7 @@ )] #![allow(clippy::new_without_default, clippy::missing_transmute_annotations)] -use std::{mem::MaybeUninit, process::ExitCode}; +use std::{fs, mem::MaybeUninit, os::yggdrasil::real_binary_path, path::Path, process::ExitCode}; use error::Error; use object::Object; @@ -27,7 +27,8 @@ pub mod thread_local; static mut OBJECTS: MaybeUninit = MaybeUninit::uninit(); -fn run(binary: &str, args: &[String]) -> Result { +fn run(binary: &Path, args: &[String]) -> Result { + log::info!("dyn-loader {binary:?}"); // Open root and its dependencies let root = Object::open(binary, true)?; let mut objects = ObjectSet::new(root); @@ -139,6 +140,13 @@ unsafe fn enter(entry: extern "C" fn(usize), argument: usize) -> ! { } } +fn real_binary(arg0: &str) -> &Path { + if fs::exists(arg0).unwrap_or(false) { + return arg0.as_ref(); + } + real_binary_path() +} + fn main() -> ExitCode { logsink::setup_logging(false); let args: Vec = std::env::args().skip(1).collect(); @@ -148,7 +156,9 @@ fn main() -> ExitCode { todo!() } - let Err(error) = run(&args[0], &args); + let real_binary = real_binary(&args[0]); + + let Err(error) = run(real_binary, &args); eprintln!("Error: {error}"); ExitCode::FAILURE } diff --git a/userspace/dyn-loader/src/object.rs b/userspace/dyn-loader/src/object.rs index d54ece7f..3205fa01 100644 --- a/userspace/dyn-loader/src/object.rs +++ b/userspace/dyn-loader/src/object.rs @@ -1,5 +1,13 @@ use std::{ - cmp, collections::HashMap, ffi::{CStr, CString}, fs::File, io::{BufReader, Read, Seek, SeekFrom}, mem, ops::Range, path::{Path, PathBuf}, ptr, rc::Rc + cmp, + ffi::{CStr, CString}, + fs::File, + io::{BufReader, Read, Seek, SeekFrom}, + mem, + ops::Range, + path::{Path, PathBuf}, + ptr, + rc::Rc, }; use elf::{ diff --git a/userspace/dyn-loader/src/relocation/x86_64.rs b/userspace/dyn-loader/src/relocation/x86_64.rs index 29b1bf67..7519103e 100644 --- a/userspace/dyn-loader/src/relocation/x86_64.rs +++ b/userspace/dyn-loader/src/relocation/x86_64.rs @@ -42,7 +42,7 @@ impl Relocation for Rela { R_X86_64_TPOFF64 => { // Need to extract fixed global offset let tls_layout = state.tls_layout.as_ref().unwrap(); - log::info!("TPOFF64: module_id={}", tls.module_id); + log::info!("TPOFF64: {name} -> module_id={}", tls.module_id); // Offset from TLS start let offset = tls_layout.offset(tls.module_id, tls.offset).unwrap(); let offset_from_tp = -((tls_layout.tp_offset - offset) as i64); diff --git a/userspace/etc/profile b/userspace/etc/profile index b7b52c71..bd2129e4 100644 --- a/userspace/etc/profile +++ b/userspace/etc/profile @@ -1 +1 @@ -export PATH=/bin:/sbin +export PATH=/mnt/bin:/bin:/sbin diff --git a/userspace/etc/test.S b/userspace/etc/test.S index 075e40d8..1dcf680f 100644 --- a/userspace/etc/test.S +++ b/userspace/etc/test.S @@ -1,4 +1,6 @@ .section .text .global _start _start: - jmp . + mov $12, %rax + mov $123, %rdi + syscall diff --git a/userspace/etc/test.c b/userspace/etc/test.c index da688795..b5e89bf2 100644 --- a/userspace/etc/test.c +++ b/userspace/etc/test.c @@ -1,3 +1,10 @@ -void _start(void) { +#include +#include +int main(int argc, char **argv) { + printf("Argument count: %d\n", argc); + for (int i = 0; i < argc; ++i) { + printf("Argument %d is %s\n", i, argv[i]); + } + return EXIT_SUCCESS; } diff --git a/userspace/etc/test.cpp b/userspace/etc/test.cpp new file mode 100644 index 00000000..383118a4 --- /dev/null +++ b/userspace/etc/test.cpp @@ -0,0 +1,6 @@ +#include + +int main(int argc, char **argv) { + std::cout << "Test!!!" << std::endl; + return 0; +} diff --git a/userspace/etc/test.sh b/userspace/etc/test.sh index 0f840cc8..67d00063 100755 --- a/userspace/etc/test.sh +++ b/userspace/etc/test.sh @@ -1,4 +1,7 @@ #!/bin/sh +/sbin/mount -t ext2 /dev/vb0p1 /mnt /mnt/bin/clang -cc1as -filetype obj -main-file-name test.S -target-cpu x86-64 -mrelocation-model pic -triple x86_64-unknown-yggdrasil -o /test.o /etc/test.S +/mnt/bin/ld.lld -nostdlib -o /test /test.o /bin/ls -lh / + diff --git a/userspace/lib/cross/src/net.rs b/userspace/lib/cross/src/net.rs index 91596d96..84cafcb9 100644 --- a/userspace/lib/cross/src/net.rs +++ b/userspace/lib/cross/src/net.rs @@ -32,6 +32,10 @@ impl LocalPacketSocket { sys::LocalPacketSocketImpl::bind(path).map(Self) } + pub fn set_nonblocking(&self, nb: bool) -> io::Result<()> { + self.0.set_nonblocking(nb) + } + pub fn receive(&self, buffer: &mut [u8]) -> io::Result { self.0.receive(buffer) } diff --git a/userspace/lib/cross/src/sys/mod.rs b/userspace/lib/cross/src/sys/mod.rs index f27bda83..d1efa82d 100644 --- a/userspace/lib/cross/src/sys/mod.rs +++ b/userspace/lib/cross/src/sys/mod.rs @@ -70,6 +70,8 @@ pub(crate) trait LocalPacketSocket: AsRawFd + Sized { fn bind>(path: P) -> io::Result; fn connect>(path: P) -> io::Result; + fn set_nonblocking(&self, nb: bool) -> io::Result<()>; + fn receive(&self, data: &mut [u8]) -> io::Result; fn receive_from(&self, data: &mut [u8]) -> io::Result<(usize, Self::OwnedAddress)>; fn receive_with_ancillary(&self, data: &mut [u8]) -> io::Result<(usize, Option)>; diff --git a/userspace/lib/cross/src/sys/yggdrasil/socket.rs b/userspace/lib/cross/src/sys/yggdrasil/socket.rs index 152d88c9..38d183a2 100644 --- a/userspace/lib/cross/src/sys/yggdrasil/socket.rs +++ b/userspace/lib/cross/src/sys/yggdrasil/socket.rs @@ -111,6 +111,11 @@ impl LocalPacketSocket for LocalPacketSocketImpl { Ok(this) } + fn set_nonblocking(&self, nb: bool) -> io::Result<()> { + runtime::rt::io::set_nonblocking(self.as_raw_fd(), nb)?; + Ok(()) + } + fn receive(&self, data: &mut [u8]) -> io::Result { let len = yggdrasil_rt::net::socket::receive(self.as_raw_fd(), data)?; Ok(len) diff --git a/userspace/lib/libcolors/src/application/connection.rs b/userspace/lib/libcolors/src/application/connection.rs index cb00da0a..aa3c62d2 100644 --- a/userspace/lib/libcolors/src/application/connection.rs +++ b/userspace/lib/libcolors/src/application/connection.rs @@ -25,6 +25,7 @@ pub struct Connection { impl Connection { pub fn new() -> Result { let channel = Channel::connect(crate::CHANNEL_NAME)?; + channel.set_nonblocking(true)?; let (sender, receiver) = channel.split(); let timeout = Duration::from_secs(1); let mut poll = Poll::new()?; @@ -63,6 +64,21 @@ impl Connection { } } + pub fn poll_event(&mut self) -> Result, Error> { + if let Some(event) = self.event_queue.pop_front() { + return Ok(Some(event)); + } + + match self.receiver.receive_with_file_from() { + Ok((data, file, _)) => { + let ServerMessage::Event(data) = data; + Ok(Some(Event { data, file })) + } + Err(error) if error.is_would_block() => Ok(None), + Err(error) => Err(error.into()) + } + } + pub fn receive_event(&mut self) -> Result { if let Some(event) = self.event_queue.pop_front() { return Ok(event); diff --git a/userspace/lib/libcolors/src/application/mod.rs b/userspace/lib/libcolors/src/application/mod.rs index 554d831a..c032c34c 100644 --- a/userspace/lib/libcolors/src/application/mod.rs +++ b/userspace/lib/libcolors/src/application/mod.rs @@ -52,7 +52,7 @@ impl<'a> Application<'a> { fn run_inner(mut self) -> Result { while self.is_running() { - self.poll_events()?; + self.wait_events()?; } Ok(ExitCode::SUCCESS) } @@ -77,7 +77,7 @@ impl<'a> Application<'a> { Ok(()) } - pub fn poll_events(&mut self) -> Result<(), Error> { + pub fn wait_events(&mut self) -> Result<(), Error> { let event = { let mut connection = self.connection.lock().unwrap(); connection.receive_event()? @@ -86,6 +86,22 @@ impl<'a> Application<'a> { self.handle_event(event) } + pub fn poll_events(&mut self) -> Result<(), Error> { + loop { + let event = { + let mut connection = self.connection.lock().unwrap(); + match connection.poll_event() { + Ok(Some(event)) => event, + Ok(None) => break, + Err(error) => return Err(error), + } + }; + + self.handle_event(event)?; + } + Ok(()) + } + pub fn run(self) -> ExitCode { match self.run_inner() { Ok(exit) => exit, diff --git a/userspace/lib/libcolors/src/application/window.rs b/userspace/lib/libcolors/src/application/window.rs index ccb68b36..4d06a80c 100644 --- a/userspace/lib/libcolors/src/application/window.rs +++ b/userspace/lib/libcolors/src/application/window.rs @@ -4,7 +4,7 @@ use cross::mem::FileMapping; use crate::{ error::Error, - event::{EventData, KeyInput, WindowEvent}, + event::{EventData, KeyEvent, KeyInput, WindowEvent}, message::{ClientMessage, CreateWindowInfo}, }; @@ -14,6 +14,8 @@ pub trait OnCloseRequested = Fn() -> EventOutcome; pub trait OnKeyInput = Fn(KeyInput) -> EventOutcome; pub trait OnResized = Fn(u32, u32) -> EventOutcome; pub trait OnFocusChanged = Fn(bool) -> EventOutcome; +pub trait OnKeyPressed = Fn(KeyEvent) -> EventOutcome; +pub trait OnKeyReleased = Fn(KeyEvent) -> EventOutcome; pub trait OnRedrawRequested = Fn(&mut [u32], u32, u32); @@ -38,6 +40,8 @@ pub struct Window<'a> { on_key_input: Box, on_resized: Box, on_focus_changed: Box, + on_key_pressed: Box, + on_key_released: Box, } impl<'a> Window<'a> { @@ -64,6 +68,8 @@ impl<'a> Window<'a> { ) }; + log::info!("Created window: #{}", create_info.window_id); + Ok(Self { connection: application.connection.clone(), window_id: create_info.window_id, @@ -82,6 +88,8 @@ impl<'a> Window<'a> { dt.fill(0xFF888888); }), on_key_input: Box::new(|_ev| EventOutcome::None), + on_key_pressed: Box::new(|_| EventOutcome::None), + on_key_released: Box::new(|_| EventOutcome::None), on_resized: Box::new(|_w, _h| EventOutcome::Redraw), on_focus_changed: Box::new(|_| EventOutcome::None), }) @@ -99,6 +107,14 @@ impl<'a> Window<'a> { self.on_key_input = Box::new(handler); } + pub fn set_on_key_pressed(&mut self, handler: H) { + self.on_key_pressed = Box::new(handler); + } + + pub fn set_on_key_released(&mut self, handler: H) { + self.on_key_released = Box::new(handler); + } + pub fn set_on_resized(&mut self, handler: H) { self.on_resized = Box::new(handler); } @@ -147,6 +163,8 @@ impl<'a> Window<'a> { (self.on_resized)(width, height) } + WindowEvent::KeyPressed(key) => (self.on_key_pressed)(key), + WindowEvent::KeyReleased(key) => (self.on_key_released)(key), WindowEvent::KeyInput(input) => (self.on_key_input)(input), WindowEvent::FocusChanged(focused) => { self.focused = focused; diff --git a/userspace/lib/uipc/src/lib.rs b/userspace/lib/uipc/src/lib.rs index b86a8233..52bca9a0 100644 --- a/userspace/lib/uipc/src/lib.rs +++ b/userspace/lib/uipc/src/lib.rs @@ -33,6 +33,15 @@ pub struct Receiver { _pd: PhantomData, } +impl Error { + pub fn is_would_block(&self) -> bool { + match self { + Self::Io(error) if error.kind() == io::ErrorKind::WouldBlock => true, + _ => false + } + } +} + #[repr(transparent)] #[derive(Debug, Clone)] pub struct PeerAddress(OwnedLocalAddress); @@ -48,6 +57,11 @@ impl Channel { Ok(Self(socket)) } + pub fn set_nonblocking(&self, nb: bool) -> Result<(), Error> { + self.0.set_nonblocking(nb)?; + Ok(()) + } + pub fn split(self) -> (Sender, Receiver) { let this = Arc::new(self); let sender = Sender { diff --git a/userspace/lib/ygglibc/include/bits/sys/wait.h b/userspace/lib/ygglibc/include/bits/sys/wait.h index 95358050..206ecad3 100644 --- a/userspace/lib/ygglibc/include/bits/sys/wait.h +++ b/userspace/lib/ygglibc/include/bits/sys/wait.h @@ -1,6 +1,8 @@ #ifndef _YGGDRASIL_SYS_WAIT_H #define _YGGDRASIL_SYS_WAIT_H 1 +// see headers/sys_wait/mod.rs + #define WEXITSTATUS(c) ((int) ((c) & 0xFF)) // TODO diff --git a/userspace/lib/ygglibc/src/cxxabi.rs b/userspace/lib/ygglibc/src/cxxabi.rs index 119e0dd0..130f7e9e 100644 --- a/userspace/lib/ygglibc/src/cxxabi.rs +++ b/userspace/lib/ygglibc/src/cxxabi.rs @@ -1,6 +1,6 @@ -use core::ffi::{c_int, c_void}; +use core::ffi::c_void; -use crate::{error::CIntZeroResult, process}; +use crate::{error::CIntZeroResult, process, thread::Thread}; #[no_mangle] unsafe extern "C" fn __cxa_atexit( @@ -14,9 +14,10 @@ unsafe extern "C" fn __cxa_atexit( #[no_mangle] unsafe extern "C" fn __cxa_thread_atexit( - _destructor: extern "C" fn(*mut c_void), - _arg: *mut c_void, - _dso_handle: *mut c_void, -) -> c_int { - todo!() + destructor: extern "C" fn(*mut c_void), + arg: *mut c_void, + dso_handle: *mut c_void, +) -> CIntZeroResult { + Thread::at_thread_exit(destructor, arg, dso_handle); + CIntZeroResult::SUCCESS } diff --git a/userspace/lib/ygglibc/src/error.rs b/userspace/lib/ygglibc/src/error.rs index cfa9f0e5..cce563e9 100644 --- a/userspace/lib/ygglibc/src/error.rs +++ b/userspace/lib/ygglibc/src/error.rs @@ -43,6 +43,7 @@ pub trait CResult { } #[must_use = "EResult must be converted into its output type with proper errno set"] +#[derive(Debug)] pub enum EResult { Ok(T), Err(Errno), diff --git a/userspace/lib/ygglibc/src/headers/fcntl/mod.rs b/userspace/lib/ygglibc/src/headers/fcntl/mod.rs index afee8bfc..f83831e9 100644 --- a/userspace/lib/ygglibc/src/headers/fcntl/mod.rs +++ b/userspace/lib/ygglibc/src/headers/fcntl/mod.rs @@ -191,13 +191,16 @@ pub(crate) unsafe extern "C" fn faccessat( ) -> CIntZeroResult { let atfd = util::at_fd(atfd)?; let path = path.ensure_str(); - let access = match mode { - 0 => AccessMode::empty(), - R_OK => AccessMode::READ, - W_OK => AccessMode::WRITE, - X_OK => AccessMode::EXEC, - _ => todo!("{mode:#x}"), - }; + let mut access = AccessMode::empty(); + if mode & R_OK != 0 { + access |= AccessMode::READ; + } + if mode & W_OK != 0 { + access |= AccessMode::WRITE; + } + if mode & X_OK != 0 { + access |= AccessMode::EXEC; + } syscall::check_access(atfd, path, access).e_map_err(Errno::from)?; CIntZeroResult::SUCCESS diff --git a/userspace/lib/ygglibc/src/headers/pthread/mutex.rs b/userspace/lib/ygglibc/src/headers/pthread/mutex.rs index adfd0e21..aa27e705 100644 --- a/userspace/lib/ygglibc/src/headers/pthread/mutex.rs +++ b/userspace/lib/ygglibc/src/headers/pthread/mutex.rs @@ -119,7 +119,7 @@ unsafe extern "C" fn pthread_mutex_consistent(_mutex: *mut pthread_mutex_t) -> c #[no_mangle] unsafe extern "C" fn pthread_mutex_destroy(_mutex: *mut pthread_mutex_t) -> c_int { - log::error!("TODO: pthread_mutex_destroy()"); + log::debug!("TODO: pthread_mutex_destroy()"); 0 } diff --git a/userspace/lib/ygglibc/src/headers/spawn/mod.rs b/userspace/lib/ygglibc/src/headers/spawn/mod.rs index 06d8fa68..672e16f6 100644 --- a/userspace/lib/ygglibc/src/headers/spawn/mod.rs +++ b/userspace/lib/ygglibc/src/headers/spawn/mod.rs @@ -1,14 +1,18 @@ use core::ffi::{c_char, c_int, c_short, c_void}; use alloc::vec::Vec; -use yggdrasil_rt::{io::RawFd, process::{SpawnFlags, SpawnOption, SpawnOptions}, sys as syscall}; +use yggdrasil_rt::{ + io::RawFd, + process::{SpawnFlags, SpawnOption, SpawnOptions}, + sys as syscall, +}; use super::{ sched::__ygg_sched_param_t, sys_types::{mode_t, pid_t}, }; use crate::{ - error::{CIntCountResult, CIntZeroResult, ResultExt}, + error::{CIntZeroResult, ResultExt}, headers::errno::Errno, util::{NullTerminatedArrayIter, PointerStrExt}, }; @@ -49,9 +53,18 @@ unsafe extern "C" fn posix_spawn( environment: &[], directory: None, optional: &[ - SpawnOption::CopyFile { source: RawFd::STDIN, child: RawFd::STDIN }, - SpawnOption::CopyFile { source: RawFd::STDOUT, child: RawFd::STDOUT }, - SpawnOption::CopyFile { source: RawFd::STDERR, child: RawFd::STDERR }, + SpawnOption::CopyFile { + source: RawFd::STDIN, + child: RawFd::STDIN, + }, + SpawnOption::CopyFile { + source: RawFd::STDOUT, + child: RawFd::STDOUT, + }, + SpawnOption::CopyFile { + source: RawFd::STDERR, + child: RawFd::STDERR, + }, ], flags: SpawnFlags::empty(), }; diff --git a/userspace/lib/ygglibc/src/headers/stdio/printf/mod.rs b/userspace/lib/ygglibc/src/headers/stdio/printf/mod.rs index 9021cef7..116162aa 100644 --- a/userspace/lib/ygglibc/src/headers/stdio/printf/mod.rs +++ b/userspace/lib/ygglibc/src/headers/stdio/printf/mod.rs @@ -56,6 +56,12 @@ impl StringWriter { position: 0, } } + + fn finish(&mut self) { + if self.position < self.capacity { + unsafe { self.buffer.add(self.position).write(0) }; + } + } } impl fmt::Write for StringWriter { @@ -272,5 +278,6 @@ unsafe extern "C" fn vsnprintf( let mut writer = StringWriter::new(buffer, capacity); let fmt = fmt.ensure_cstr(); let count = printf_inner(&mut writer, fmt.to_bytes(), args)?; + writer.finish(); CIntCountResult::success(count.try_into().unwrap()) } diff --git a/userspace/lib/ygglibc/src/headers/stdlib/process.rs b/userspace/lib/ygglibc/src/headers/stdlib/process.rs index d2de8d97..20a4976f 100644 --- a/userspace/lib/ygglibc/src/headers/stdlib/process.rs +++ b/userspace/lib/ygglibc/src/headers/stdlib/process.rs @@ -66,8 +66,10 @@ unsafe extern "C" fn setkey(_key: *const c_char) { } #[no_mangle] -unsafe extern "C" fn system(_command: *const c_char) -> CIntZeroResult { - todo!() +unsafe extern "C" fn system(command: *const c_char) -> CIntZeroResult { + let command = command.ensure_str(); + log::warn!("system({command:?})"); + CIntZeroResult::ERROR } #[no_mangle] diff --git a/userspace/lib/ygglibc/src/headers/string/str.rs b/userspace/lib/ygglibc/src/headers/string/str.rs index 80b7309d..8725e8cc 100644 --- a/userspace/lib/ygglibc/src/headers/string/str.rs +++ b/userspace/lib/ygglibc/src/headers/string/str.rs @@ -27,8 +27,9 @@ unsafe extern "C" fn stpncpy(dst: *mut c_char, src: *const c_char, n: usize) -> if dst.is_null() || src.is_null() { panic!(); } - memset(dst.cast(), 0, n); - mempcpy(dst.cast(), src.cast(), strnlen(src, n)).cast() + let dlen = strnlen(src.cast(), n); + let r = mempcpy(dst.cast(), src.cast(), n); + memset(r.cast(), 0, n - dlen).cast() } #[no_mangle] @@ -164,8 +165,21 @@ unsafe extern "C" fn strncmp(mut a: *const c_char, mut b: *const c_char, mut n: #[no_mangle] unsafe extern "C" fn strncpy(dst: *mut c_char, src: *const c_char, n: usize) -> *mut c_char { - stpncpy(dst, src, n); + if dst.is_null() || src.is_null() { + panic!(); + } + let mut i = 0; + while i != n { + let c = *src.add(i); + *dst.add(i) = c; + if c == 0 { + break; + } + i += 1; + } dst + // stpncpy(dst, src, n); + // dst } #[no_mangle] diff --git a/userspace/lib/ygglibc/src/headers/strings/mod.rs b/userspace/lib/ygglibc/src/headers/strings/mod.rs index fca94022..012c31a9 100644 --- a/userspace/lib/ygglibc/src/headers/strings/mod.rs +++ b/userspace/lib/ygglibc/src/headers/strings/mod.rs @@ -1,6 +1,6 @@ use core::{ cmp::Ordering, - ffi::{c_char, c_int}, + ffi::{c_char, c_int, CStr}, }; use super::locale::locale_t; @@ -26,6 +26,16 @@ unsafe extern "C" fn strcasecmp_l( #[no_mangle] unsafe extern "C" fn strncasecmp(s1: *const c_char, s2: *const c_char, n: usize) -> c_int { + if s1.is_null() { + if s2.is_null() { + return 0; + } else { + return 1; + } + } else if s2.is_null() { + return -1; + } + for i in 0..n { let c0 = (*s1.add(i) as u8).to_ascii_lowercase(); let c1 = (*s2.add(i) as u8).to_ascii_lowercase(); diff --git a/userspace/lib/ygglibc/src/headers/sys_mman/mod.rs b/userspace/lib/ygglibc/src/headers/sys_mman/mod.rs index 3803feee..0a12d720 100644 --- a/userspace/lib/ygglibc/src/headers/sys_mman/mod.rs +++ b/userspace/lib/ygglibc/src/headers/sys_mman/mod.rs @@ -10,7 +10,7 @@ use yggdrasil_rt::{ }; use crate::{ - error::{self, EResult, ResultExt, TryFromExt}, + error::{self, CIntZeroResult, CResult, EResult, ResultExt, TryFromExt}, headers::errno::Errno, }; @@ -51,7 +51,7 @@ unsafe fn mmap_inner( hint: *mut c_void, len: usize, prot: c_int, - flags: c_int, + _flags: c_int, fd: c_int, offset: off_t, ) -> EResult> { @@ -73,9 +73,9 @@ unsafe fn mmap_inner( if prot & PROT_WRITE != 0 { mapping_flags |= MappingFlags::WRITE; } - if flags != MAP_PRIVATE { - todo!("Non-private mappings via mmap(2) are not yet supported"); - } + // if flags != MAP_PRIVATE { + // todo!("Non-private mappings via mmap(2) are not yet supported"); + // } let address = syscall::map_memory(hint, len, mapping_flags, &source).e_map_err(Errno::from)?; assert_ne!(address, 0); @@ -143,8 +143,14 @@ unsafe extern "C" fn mmap( } #[no_mangle] -unsafe extern "C" fn munmap(_ptr: *mut c_void, _len: usize) -> c_int { - todo!() +unsafe extern "C" fn munmap(ptr: *mut c_void, len: usize) -> CIntZeroResult { + let address = ptr.addr(); + if address == 0 || address == usize::MAX || len == 0 { + error::errno = Errno::EINVAL; + return CIntZeroResult::ERROR; + } + syscall::unmap_memory(address, len).e_map_err(Errno::from)?; + CIntZeroResult::SUCCESS } // posix_*** diff --git a/userspace/lib/ygglibc/src/headers/sys_resource/cbindgen.toml b/userspace/lib/ygglibc/src/headers/sys_resource/cbindgen.toml index 1159751c..002b6e85 100644 --- a/userspace/lib/ygglibc/src/headers/sys_resource/cbindgen.toml +++ b/userspace/lib/ygglibc/src/headers/sys_resource/cbindgen.toml @@ -10,4 +10,4 @@ usize_type = "size_t" isize_type = "ssize_t" [export] -include = ["rlimit", "rusage"] +include = ["rlimit", "rusage", "__ygg_rusage_t"] diff --git a/userspace/lib/ygglibc/src/headers/sys_resource/mod.rs b/userspace/lib/ygglibc/src/headers/sys_resource/mod.rs index 07f5f102..bde3bfb0 100644 --- a/userspace/lib/ygglibc/src/headers/sys_resource/mod.rs +++ b/userspace/lib/ygglibc/src/headers/sys_resource/mod.rs @@ -4,6 +4,8 @@ use super::{sys_time::__ygg_timeval_t, sys_types::id_t}; pub type rlim_t = u64; +pub type __ygg_rusage_t = rusage; + pub const PRIO_PROCESS: c_int = 0; pub const PRIO_PGRP: c_int = 1; pub const PRIO_USER: c_int = 2; diff --git a/userspace/lib/ygglibc/src/headers/sys_stat/mod.rs b/userspace/lib/ygglibc/src/headers/sys_stat/mod.rs index 20953b3e..763ea66b 100644 --- a/userspace/lib/ygglibc/src/headers/sys_stat/mod.rs +++ b/userspace/lib/ygglibc/src/headers/sys_stat/mod.rs @@ -73,8 +73,9 @@ impl From for stat { let st_uid = u32::from(value.uid).try_into().unwrap(); let st_gid = u32::from(value.gid).try_into().unwrap(); // TODO - let st_blksize = 512; + let st_blksize = value.block_size as _; let st_blocks = st_size.div_ceil(st_blksize as _).try_into().unwrap(); + let st_ino = value.inode.unwrap_or(0) as u64; Self { st_mode, @@ -83,6 +84,7 @@ impl From for stat { st_gid, st_blksize, st_blocks, + st_ino, ..Default::default() } } @@ -125,14 +127,13 @@ unsafe extern "C" fn mkdir(pathname: *const c_char, mode: mode_t) -> CIntZeroRes #[no_mangle] unsafe extern "C" fn mkdirat(atfd: c_int, pathname: *const c_char, mode: mode_t) -> CIntZeroResult { - let _pathname = pathname.ensure_str(); - let _atfd = util::at_fd(atfd)?; - let _mode = FileMode::new((mode & 0o777) as u32); + let pathname = pathname.ensure_str(); + let atfd = util::at_fd(atfd)?; + let mode = FileMode::new((mode & 0o777) as u32); - todo!() - // io::create_directory(atfd, pathname, mode)?; + io::create_directory(atfd, pathname, mode)?; - // CIntZeroResult::OK + CIntZeroResult::SUCCESS } #[no_mangle] diff --git a/userspace/lib/ygglibc/src/headers/sys_wait/cbindgen.toml b/userspace/lib/ygglibc/src/headers/sys_wait/cbindgen.toml index 230ef9e0..8db8c23f 100644 --- a/userspace/lib/ygglibc/src/headers/sys_wait/cbindgen.toml +++ b/userspace/lib/ygglibc/src/headers/sys_wait/cbindgen.toml @@ -7,6 +7,7 @@ sys_includes = [ "stdint.h", "signal.h", "sys/types.h", + "sys/resource.h", "bits/sys/wait.h" ] no_includes = true diff --git a/userspace/lib/ygglibc/src/headers/sys_wait/mod.rs b/userspace/lib/ygglibc/src/headers/sys_wait/mod.rs index 3b06511e..671ea471 100644 --- a/userspace/lib/ygglibc/src/headers/sys_wait/mod.rs +++ b/userspace/lib/ygglibc/src/headers/sys_wait/mod.rs @@ -1,6 +1,18 @@ use core::ffi::{c_int, c_void}; -use super::sys_types::{id_t, pid_t}; +use yggdrasil_rt::{ + process::{ExitCode, ProcessGroupId, ProcessId, ProcessWait, WaitFlags}, + sys as syscall, +}; + +use crate::error::{self, EResult, ResultExt}; + +use super::{ + errno::Errno, + sys_resource::__ygg_rusage_t, + sys_time::timeval, + sys_types::{id_t, pid_t}, +}; pub const WCONTINUED: c_int = 1 << 0; pub const WNOHANG: c_int = 1 << 1; @@ -16,6 +28,45 @@ pub const P_ALL: idtype_t = 0; pub const P_PGID: idtype_t = 1; pub const P_PID: idtype_t = 2; +pub struct WaitResult { + pid: ProcessId, + status: ExitCode, +} + +fn wait_inner(what: ProcessWait, nonblocking: bool) -> EResult { + let mut status = ExitCode::Exited(0); + let mut flags = WaitFlags::empty(); + if nonblocking { + flags |= WaitFlags::NON_BLOCKING; + } + let pid = unsafe { syscall::wait_process(&what, &mut status, flags) }.e_map_err(Errno::from)?; + + EResult::Ok(WaitResult { pid, status }) +} + +fn convert_wait_pid(pid: pid_t) -> ProcessWait { + // TODO "any child whose process group ID is equal to that of the calling process" + if pid > 0 { + ProcessWait::Process(unsafe { ProcessId::from_raw(pid as _) }) + } else if pid == -1 || pid == 0 { + ProcessWait::AnyChild + } else { + let pgrp = (-pid) as u32; + ProcessWait::Group(unsafe { ProcessGroupId::from_raw(pgrp) }) + } +} + +fn encode_exit_status(code: ExitCode) -> c_int { + match code { + ExitCode::Exited(status) => status & 0xFF, + ExitCode::BySignal(Ok(sig)) => { + let signum = sig as u32; + (signum + 0x100) as c_int + } + ExitCode::BySignal(Err(signum)) => (signum + 0x100) as c_int, + } +} + #[no_mangle] unsafe extern "C" fn wait(_status: *mut c_int) -> pid_t { todo!() @@ -36,3 +87,29 @@ unsafe extern "C" fn waitid( unsafe extern "C" fn waitpid(_pid: pid_t, _status: *mut c_int, _options: c_int) -> pid_t { todo!() } + +#[no_mangle] +unsafe extern "C" fn wait4( + pid: pid_t, + wstatus: *mut c_int, + options: c_int, + rusage: *mut __ygg_rusage_t, +) -> pid_t { + let pid = convert_wait_pid(pid); + let result = match wait_inner(pid, options & WNOHANG != 0) { + EResult::Ok(result) => result, + EResult::Err(err) => { + error::errno = err; + return -1; + } + }; + if let Some(wstatus) = wstatus.as_mut() { + *wstatus = encode_exit_status(result.status); + } + if let Some(rusage) = rusage.as_mut() { + // TODO not implemented on the kernel level + rusage.ru_utime = timeval::zero(); + rusage.ru_stime = timeval::zero(); + } + result.pid.bits() as pid_t +} diff --git a/userspace/lib/ygglibc/src/io/mod.rs b/userspace/lib/ygglibc/src/io/mod.rs index 4f93c06d..d0014312 100644 --- a/userspace/lib/ygglibc/src/io/mod.rs +++ b/userspace/lib/ygglibc/src/io/mod.rs @@ -1,7 +1,7 @@ use core::{ffi::c_int, mem::MaybeUninit}; use yggdrasil_rt::{ - io::{FileAttr, RawFd, SeekFrom}, path::{Path, PathBuf}, sys as syscall + io::{FileAttr, FileMode, RawFd, SeekFrom}, path::{Path, PathBuf}, sys as syscall }; use crate::{ @@ -127,6 +127,11 @@ pub fn get_metadata(at: Option, path: &str, follow: bool) -> EResult, path: &str, mode: FileMode) -> EResult<()> { + unsafe { syscall::create_directory(at, path, mode) }?; + EResult::Ok(()) +} + pub fn realpath>(path: P) -> EResult { // Cases: // * /a/b/c -> /a/b/c diff --git a/userspace/lib/ygglibc/src/lib.rs b/userspace/lib/ygglibc/src/lib.rs index 2e87b0cc..0cbf522d 100644 --- a/userspace/lib/ygglibc/src/lib.rs +++ b/userspace/lib/ygglibc/src/lib.rs @@ -34,6 +34,7 @@ use core::{ use alloc::vec::Vec; use env::environ; +use thread::Thread; extern crate alloc; @@ -71,6 +72,13 @@ unsafe extern "C" fn __ygglibc_entry( signal::init(true); init::init(); + let sp = unsafe { + let sp: usize; + core::arch::asm!("mov %rsp, {0}", out(reg) sp, options(att_syntax)); + sp + }; + log::info!("sp = {sp:#x}"); + // Setup args let args = env::handle_kernel_argument(arg); let mut c_args = Vec::new(); @@ -86,5 +94,8 @@ unsafe extern "C" fn __ygglibc_entry( environ.cast(), ); + // Call main thread dtors + Thread::call_thread_dtors(); + process::c_exit(status) } diff --git a/userspace/lib/ygglibc/src/thread/mod.rs b/userspace/lib/ygglibc/src/thread/mod.rs index cdc6abe7..8b529b98 100644 --- a/userspace/lib/ygglibc/src/thread/mod.rs +++ b/userspace/lib/ygglibc/src/thread/mod.rs @@ -1,6 +1,6 @@ -use core::{ffi::c_void, ptr::null_mut}; +use core::{cell::RefCell, ffi::c_void, ptr::null_mut}; -use alloc::{boxed::Box, collections::BTreeMap}; +use alloc::{boxed::Box, collections::BTreeMap, vec::Vec}; use yggdrasil_rt::{ process::{ thread::{self as rt, ThreadCreateInfo}, @@ -12,13 +12,21 @@ use yggdrasil_rt::{ use crate::{ error::{EResult, OptionExt}, headers::{ - errno::Errno, sys_types::{pthread_attr_t, pthread_t} + errno::Errno, + sys_types::{pthread_attr_t, pthread_t}, }, }; pub mod tls; +pub struct ThreadDestructor { + pub destructor: extern "C" fn(*mut c_void), + pub argument: *mut c_void, +} + static THREADS: Mutex> = Mutex::new(BTreeMap::new()); +#[thread_local] +static THREAD_LOCAL_DTORS: RefCell> = RefCell::new(Vec::new()); pub const DEFAULT_STACK_SIZE: usize = 4096 * 16; pub const DEFAULT_SIGNAL_STACK_SIZE: usize = 4096 * 8; @@ -49,7 +57,7 @@ impl Thread { signal_stack: rt::ThreadSignalStack::Allocate(DEFAULT_SIGNAL_STACK_SIZE), stack, #[allow(clippy::redundant_closure)] - entry: rt::ThreadFunction::Closure(Box::new(move |arg| entry(arg))), + entry: rt::ThreadFunction::Closure(Box::new(move |arg| Self::thread_main(entry, arg))), tls_image: tls::TLS_IMAGE.get().as_ref(), }; let handle = rt::Thread::spawn(info, argument, true)?; @@ -68,6 +76,32 @@ impl Thread { pub fn this() -> EResult { EResult::Ok(unsafe { rt::Thread::<*mut c_void>::current().id() }) } + + fn thread_main( + entry: extern "C" fn(*mut c_void) -> *mut c_void, + arg: *mut c_void, + ) -> *mut c_void { + let ret = entry(arg); + unsafe { Self::call_thread_dtors() }; + ret + } + + pub fn at_thread_exit( + destructor: extern "C" fn(*mut c_void), + argument: *mut c_void, + _dso_handle: *mut c_void, + ) { + THREAD_LOCAL_DTORS.borrow_mut().push(ThreadDestructor { + destructor, + argument, + }); + } + + pub unsafe fn call_thread_dtors() { + for dtor in THREAD_LOCAL_DTORS.borrow().iter() { + (dtor.destructor)(dtor.argument); + } + } } pub fn init_main_thread(arg: &ProgramArgumentInner) { diff --git a/userspace/shell/src/syntax/lex.rs b/userspace/shell/src/syntax/lex.rs index 0d5e10b8..6c18e539 100644 --- a/userspace/shell/src/syntax/lex.rs +++ b/userspace/shell/src/syntax/lex.rs @@ -141,7 +141,7 @@ fn lex_identifier(i: &str) -> IResult<&str, &str> { recognize(many1_count(alt((alphanumeric1, is_a("-_")))))(i) } fn lex_filename(i: &str) -> IResult<&str, &str> { - recognize(many1_count(alt((alphanumeric1, is_a("./-_:")))))(i) + recognize(many1_count(alt((alphanumeric1, is_a("./-_:+")))))(i) } fn lex_braced_var(i: &str) -> IResult<&str, &str> { diff --git a/userspace/sysutils/src/tst.rs b/userspace/sysutils/src/tst.rs index e847cffb..d2651f34 100644 --- a/userspace/sysutils/src/tst.rs +++ b/userspace/sysutils/src/tst.rs @@ -1,12 +1,14 @@ -use std::{io::{stdout, Write}, process::Command}; +#![feature(seek_stream_len)] + +use std::{fs::File, io::{stdout, Seek, Write}}; + +use cross::mem::FileMapping; fn main() { - let output = Command::new("/bin/ls").output().unwrap(); - println!("status = {:?}", output.status); - println!("stdout:"); - stdout().write_all(&output.stdout).ok(); - println!(); - println!("stderr:"); - stdout().write_all(&output.stderr).ok(); - println!(); + let mut file = File::open("/etc/test.txt").unwrap(); + let size = file.stream_len().unwrap(); + let mapping = FileMapping::map(file, size as usize).unwrap(); + let mut data = vec![0; size as usize]; + data.copy_from_slice(&mapping[..]); + stdout().write_all(&data).unwrap(); } diff --git a/userspace/term/src/main.rs b/userspace/term/src/main.rs index 611e1563..e7d8d334 100644 --- a/userspace/term/src/main.rs +++ b/userspace/term/src/main.rs @@ -362,6 +362,7 @@ impl Terminal<'_> { static ABORT: AtomicBool = AtomicBool::new(false); fn main() -> ExitCode { + logsink::setup_logging(false); let font = PcScreenFont::default(); let term = Terminal::new(font).unwrap(); diff --git a/xtask/src/build/c.rs b/xtask/src/build/c.rs index a8d39771..63b7da4a 100644 --- a/xtask/src/build/c.rs +++ b/xtask/src/build/c.rs @@ -1,3 +1,4 @@ +#![allow(unused)] use std::{ fs, path::{Path, PathBuf}, @@ -126,19 +127,25 @@ fn build_test_c_program( fn install_ygglibc(env: &BuildEnv, ygglibc: &Ygglibc) -> Result<(), Error> { log::info!("Installing ygglibc into LLVM sysroot"); - let dst_lib_dir = env.llvm_sysroot.join("lib"); - let dst_include_dir = env.llvm_sysroot.join("usr/include"); + // let dst_lib_dir = env.llvm_sysroot.join("lib"); + // let dst_include_dir = env.llvm_sysroot.join("usr/include"); + let _ = env; + let _ = ygglibc.crt0_file; - fs::create_dir_all(&dst_lib_dir)?; - fs::create_dir_all(&dst_include_dir)?; + // fs::create_dir_all(&dst_lib_dir)?; + // fs::create_dir_all(&dst_include_dir)?; - fs::copy(&ygglibc.static_lib_file, dst_lib_dir.join("libygglibc.a"))?; - fs::copy(&ygglibc.shared_lib_file, dst_lib_dir.join("libygglibc.so"))?; - fs::copy(&ygglibc.crt0_file, dst_lib_dir.join("crt0.o"))?; + // fs::copy(&ygglibc.static_lib_file, dst_lib_dir.join("libygglibc.a"))?; + // fs::copy(&ygglibc.shared_lib_file, dst_lib_dir.join("libygglibc.so"))?; + // fs::copy(&ygglibc.crt0_file, dst_lib_dir.join("crt0.o"))?; - for path in ygglibc.include_paths.iter() { - util::copy_dir_recursive(path, &dst_include_dir)?; - } + let _ = ygglibc.static_lib_file; + let _ = ygglibc.shared_lib_file; + let _ = ygglibc.include_paths; + + // for path in ygglibc.include_paths.iter() { + // util::copy_dir_recursive(path, &dst_include_dir)?; + // } Ok(()) } @@ -212,7 +219,8 @@ fn install_openlibm(env: &BuildEnv, libm: &Openlibm) -> Result<(), Error> { fs::copy(&libm.static_lib_file, env.llvm_sysroot.join("lib/libm.a"))?; fs::copy(&libm.shared_lib_file, env.llvm_sysroot.join("lib/libm.so"))?; - util::copy_dir_recursive(&libm.include_path, env.llvm_sysroot.join("usr/include"))?; + let _ = libm.include_path; + // util::copy_dir_recursive(&libm.include_path, env.llvm_sysroot.join("usr/include"))?; Ok(()) } @@ -241,6 +249,7 @@ pub fn build_c(env: &BuildEnv, install: &mut Vec<(PathBuf, PathBuf)>) -> Result< "lib/libc++.so".into(), )); } + install.push((ygglibc.crt0_file, "lib/crt0.o".into())); install.push((ygglibc.shared_lib_file, "lib/libygglibc.so".into())); install.push((libm.shared_lib_file, "lib/libopenlibm.so.4".into()));