Files
RedBear-OS/src/header/_todo/oldlib/lib.rs
T
2018-08-26 08:11:35 -06:00

212 lines
5.5 KiB
Rust

#![no_std]
#![feature(
alloc,
allocator_api,
alloc_system,
compiler_builtins_lib,
const_fn,
const_ptr_null,
core_intrinsics,
global_allocator,
lang_items,
linkage,
const_size_of,
const_cell_new,
)]
#[macro_use]
extern crate alloc;
extern crate alloc_system;
extern crate byteorder;
extern crate compiler_builtins;
extern crate libc;
extern crate syscall;
extern crate redox_termios;
use alloc::Vec;
use alloc::String;
use alloc::fmt::Write;
use alloc::boxed::Box;
use core::{ptr, mem, intrinsics, slice, str};
use libc::{c_int, c_void, c_char, size_t};
#[macro_use]
mod macros;
mod types;
mod dns;
mod mallocnull;
mod rawfile;
pub mod event;
pub mod process;
pub mod file;
pub mod folder;
pub mod time;
pub mod unimpl;
pub mod user;
pub mod redox;
pub mod socket;
pub mod hostname;
pub mod termios;
pub mod netdb;
pub use mallocnull::MallocNull;
pub use rawfile::RawFile;
#[global_allocator]
static ALLOCATOR: alloc_system::System = alloc_system::System;
extern "C" {
// Newlib uses this function instead of just a global to support reentrancy
pub fn __errno() -> *mut c_int;
pub fn malloc(size: size_t) -> *mut c_void;
pub fn free(ptr: *mut c_void);
pub fn strlen(s: *const c_char) -> size_t;
pub fn __libc_fini_array();
pub static mut environ: *mut *mut c_char;
}
pub unsafe fn cstr_to_slice<'a>(buf: *const c_char) -> &'a [u8] {
slice::from_raw_parts(buf as *const u8, ::strlen(buf) as usize)
}
pub unsafe fn cstr_to_slice_mut<'a>(buf: *const c_char) -> &'a mut [u8] {
slice::from_raw_parts_mut(buf as *mut u8, ::strlen(buf) as usize)
}
pub fn file_read_all<T: AsRef<[u8]>>(path: T) -> syscall::Result<Vec<u8>> {
let fd = RawFile::open(path, syscall::O_RDONLY)?;
let mut st = syscall::Stat::default();
syscall::fstat(*fd, &mut st)?;
let size = st.st_size as usize;
let mut buf = Vec::with_capacity(size);
unsafe { buf.set_len(size) };
syscall::read(*fd, buf.as_mut_slice())?;
Ok(buf)
}
/// Implements an `Iterator` which returns on either newline or EOF.
#[derive(Clone, Copy)]
pub struct RawLineBuffer {
fd: usize,
cur: usize,
read: usize,
buf: [u8; 8 * 1024],
}
impl Default for RawLineBuffer {
fn default() -> RawLineBuffer {
RawLineBuffer {
fd: 0,
cur: 0,
read: 0,
buf: unsafe { mem::uninitialized() },
}
}
}
impl RawLineBuffer {
fn new(fd: usize) -> RawLineBuffer {
RawLineBuffer {
fd: fd,
cur: 0,
read: 0,
buf: unsafe { mem::uninitialized() },
}
}
}
impl Iterator for RawLineBuffer {
type Item = syscall::Result<Box<str>>;
fn next(&mut self) -> Option<Self::Item> {
if self.cur != 0 && self.read != 0 {
if let Some(mut pos) = self.buf[self.cur..self.read].iter().position(
|&x| x == b'\n',
)
{
pos += self.cur + 1;
let line = unsafe { str::from_utf8_unchecked(&self.buf[self.cur..pos]) };
let boxed_array: Box<[u8]> = Box::from(line.as_bytes());
let boxed_line: Box<str> = unsafe { mem::transmute(boxed_array) };
self.cur = pos;
return Some(Ok(boxed_line));
}
let mut temp: [u8; 8 * 1024] = unsafe { mem::uninitialized() };
unsafe {
ptr::copy(self.buf[self.cur..].as_ptr(), temp.as_mut_ptr(), self.read);
ptr::swap(self.buf.as_mut_ptr(), temp.as_mut_ptr());
};
self.read -= self.cur;
self.cur = 0;
}
let end = match syscall::read(self.fd, &mut self.buf[self.cur..]).unwrap() {
0 => return None,
read => {
self.read += read;
self.buf[..self.read]
.iter()
.position(|&x| x == b'\n')
.unwrap_or(0)
}
};
self.cur = end;
let line = unsafe { str::from_utf8_unchecked(&self.buf[..end]) };
let boxed_array: Box<[u8]> = Box::from(line.as_bytes());
let boxed_line: Box<str> = unsafe { mem::transmute(boxed_array) };
Some(Ok(boxed_line))
}
}
#[no_mangle]
pub unsafe extern "C" fn __errno_location() -> *mut c_int {
__errno()
}
#[lang = "eh_personality"]
pub extern "C" fn eh_personality() {}
#[lang = "panic_fmt"]
#[linkage = "weak"]
#[no_mangle]
pub extern "C" fn rust_begin_unwind(_msg: core::fmt::Arguments,
_file: &'static str,
_line: u32,
_col: u32) -> ! {
let mut s = String::new();
let _ = s.write_fmt(_msg);
let _ = syscall::write(2, _file.as_bytes());
let _ = syscall::write(2, "\n".as_bytes());
let _ = syscall::write(2, s.as_bytes());
let _ = syscall::write(2, "\n".as_bytes());
unsafe { intrinsics::abort() }
}
libc_fn!(unsafe initialize_standard_library() {
let mut buf = file_read_all("env:").unwrap();
let size = buf.len();
buf.push(0);
let mut vars = Vec::new();
vars.push(&mut buf[0] as *mut u8 as *mut c_char);
for i in 0..size {
if buf[i] == b'\n' {
if i != size - 1 {
vars.push(&mut buf[i + 1] as *mut u8 as *mut c_char);
}
buf[i] = b'\0';
}
}
vars.push(ptr::null_mut());
environ = vars.as_mut_ptr();
mem::forget(vars); // Do not free memory
mem::forget(buf);
});