libc/colors: non-blocking local socket + fixed string bugs in libc
This commit is contained in:
parent
7fdc57fd9f
commit
43acdb9e13
@ -129,7 +129,7 @@ impl SocketWrapper {
|
||||
non_blocking: bool,
|
||||
) -> Result<usize, Error> {
|
||||
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)?
|
||||
|
@ -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::<options::NonBlocking>(fd, &nonblocking)
|
||||
}
|
||||
|
16
test.c
16
test.c
@ -1,16 +1,12 @@
|
||||
#include <string.h>
|
||||
#include <dlfcn.h>
|
||||
#include <stdio.h>
|
||||
|
||||
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;
|
||||
}
|
||||
|
@ -43,6 +43,8 @@ impl InputState {
|
||||
b'.' => b'>',
|
||||
b'`' => b'~',
|
||||
b'\\' => b'|',
|
||||
b'[' => b'{',
|
||||
b']' => b'}',
|
||||
_ => ch,
|
||||
}
|
||||
}
|
||||
|
@ -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,7 +152,12 @@ 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);
|
||||
@ -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);
|
||||
|
||||
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,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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<ObjectSet> = MaybeUninit::uninit();
|
||||
|
||||
fn run(binary: &str, args: &[String]) -> Result<!, Error> {
|
||||
fn run(binary: &Path, args: &[String]) -> Result<!, Error> {
|
||||
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<String> = 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
|
||||
}
|
||||
|
@ -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::{
|
||||
|
@ -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);
|
||||
|
@ -1 +1 @@
|
||||
export PATH=/bin:/sbin
|
||||
export PATH=/mnt/bin:/bin:/sbin
|
||||
|
@ -1,4 +1,6 @@
|
||||
.section .text
|
||||
.global _start
|
||||
_start:
|
||||
jmp .
|
||||
mov $12, %rax
|
||||
mov $123, %rdi
|
||||
syscall
|
||||
|
@ -1,3 +1,10 @@
|
||||
void _start(void) {
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
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;
|
||||
}
|
||||
|
6
userspace/etc/test.cpp
Normal file
6
userspace/etc/test.cpp
Normal file
@ -0,0 +1,6 @@
|
||||
#include <iostream>
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
std::cout << "Test!!!" << std::endl;
|
||||
return 0;
|
||||
}
|
@ -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 /
|
||||
|
||||
|
@ -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<usize> {
|
||||
self.0.receive(buffer)
|
||||
}
|
||||
|
@ -70,6 +70,8 @@ pub(crate) trait LocalPacketSocket: AsRawFd + Sized {
|
||||
fn bind<P: AsRef<Path>>(path: P) -> io::Result<Self>;
|
||||
fn connect<P: AsRef<Path>>(path: P) -> io::Result<Self>;
|
||||
|
||||
fn set_nonblocking(&self, nb: bool) -> io::Result<()>;
|
||||
|
||||
fn receive(&self, data: &mut [u8]) -> io::Result<usize>;
|
||||
fn receive_from(&self, data: &mut [u8]) -> io::Result<(usize, Self::OwnedAddress)>;
|
||||
fn receive_with_ancillary(&self, data: &mut [u8]) -> io::Result<(usize, Option<OwnedFd>)>;
|
||||
|
@ -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<usize> {
|
||||
let len = yggdrasil_rt::net::socket::receive(self.as_raw_fd(), data)?;
|
||||
Ok(len)
|
||||
|
@ -25,6 +25,7 @@ pub struct Connection {
|
||||
impl Connection {
|
||||
pub fn new() -> Result<Self, Error> {
|
||||
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<Option<Event>, 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<Event, Error> {
|
||||
if let Some(event) = self.event_queue.pop_front() {
|
||||
return Ok(event);
|
||||
|
@ -52,7 +52,7 @@ impl<'a> Application<'a> {
|
||||
|
||||
fn run_inner(mut self) -> Result<ExitCode, Error> {
|
||||
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,
|
||||
|
@ -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<dyn OnKeyInput>,
|
||||
on_resized: Box<dyn OnResized>,
|
||||
on_focus_changed: Box<dyn OnFocusChanged>,
|
||||
on_key_pressed: Box<dyn OnKeyPressed>,
|
||||
on_key_released: Box<dyn OnKeyReleased>,
|
||||
}
|
||||
|
||||
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<H: OnKeyPressed + 'static>(&mut self, handler: H) {
|
||||
self.on_key_pressed = Box::new(handler);
|
||||
}
|
||||
|
||||
pub fn set_on_key_released<H: OnKeyReleased + 'static>(&mut self, handler: H) {
|
||||
self.on_key_released = Box::new(handler);
|
||||
}
|
||||
|
||||
pub fn set_on_resized<H: OnResized + 'static>(&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;
|
||||
|
@ -33,6 +33,15 @@ pub struct Receiver<T> {
|
||||
_pd: PhantomData<T>,
|
||||
}
|
||||
|
||||
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<T: Serialize, U: DeserializeOwned>(self) -> (Sender<T>, Receiver<U>) {
|
||||
let this = Arc::new(self);
|
||||
let sender = Sender {
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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<T> {
|
||||
Ok(T),
|
||||
Err(Errno),
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
@ -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(),
|
||||
};
|
||||
|
@ -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())
|
||||
}
|
||||
|
@ -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]
|
||||
|
@ -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]
|
||||
|
@ -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();
|
||||
|
@ -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<NonNull<c_void>> {
|
||||
@ -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_***
|
||||
|
@ -10,4 +10,4 @@ usize_type = "size_t"
|
||||
isize_type = "ssize_t"
|
||||
|
||||
[export]
|
||||
include = ["rlimit", "rusage"]
|
||||
include = ["rlimit", "rusage", "__ygg_rusage_t"]
|
||||
|
@ -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;
|
||||
|
@ -73,8 +73,9 @@ impl From<FileAttr> 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<FileAttr> 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]
|
||||
|
@ -7,6 +7,7 @@ sys_includes = [
|
||||
"stdint.h",
|
||||
"signal.h",
|
||||
"sys/types.h",
|
||||
"sys/resource.h",
|
||||
"bits/sys/wait.h"
|
||||
]
|
||||
no_includes = true
|
||||
|
@ -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<WaitResult> {
|
||||
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
|
||||
}
|
||||
|
@ -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<RawFd>, path: &str, follow: bool) -> EResult<File
|
||||
EResult::Ok(unsafe { metadata.assume_init() })
|
||||
}
|
||||
|
||||
pub fn create_directory(at: Option<RawFd>, path: &str, mode: FileMode) -> EResult<()> {
|
||||
unsafe { syscall::create_directory(at, path, mode) }?;
|
||||
EResult::Ok(())
|
||||
}
|
||||
|
||||
pub fn realpath<P: AsRef<Path>>(path: P) -> EResult<PathBuf> {
|
||||
// Cases:
|
||||
// * /a/b/c -> /a/b/c
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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<BTreeMap<pthread_t, Thread>> = Mutex::new(BTreeMap::new());
|
||||
#[thread_local]
|
||||
static THREAD_LOCAL_DTORS: RefCell<Vec<ThreadDestructor>> = 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<pthread_t> {
|
||||
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) {
|
||||
|
@ -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> {
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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()));
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user