271 lines
6.5 KiB
Rust
271 lines
6.5 KiB
Rust
use alloc::vec::Vec;
|
|
use core::{fmt, ptr};
|
|
use io::{self, Read, Write};
|
|
|
|
pub use self::allocator::*;
|
|
|
|
#[cfg(not(feature = "ralloc"))]
|
|
#[path = "allocator/dlmalloc.rs"]
|
|
mod allocator;
|
|
|
|
#[cfg(feature = "ralloc")]
|
|
#[path = "allocator/ralloc.rs"]
|
|
mod allocator;
|
|
|
|
pub use self::pal::{Pal, PalEpoll, PalSignal, PalSocket};
|
|
|
|
mod pal;
|
|
|
|
pub use self::sys::{e, Sys};
|
|
|
|
#[cfg(all(not(feature = "no_std"), target_os = "linux"))]
|
|
#[path = "linux/mod.rs"]
|
|
mod sys;
|
|
|
|
#[cfg(all(not(feature = "no_std"), target_os = "redox"))]
|
|
#[path = "redox/mod.rs"]
|
|
mod sys;
|
|
|
|
mod pte;
|
|
|
|
pub use self::rlb::{Line, RawLineBuffer};
|
|
pub mod rlb;
|
|
|
|
use self::types::*;
|
|
pub mod types;
|
|
|
|
#[thread_local]
|
|
#[allow(non_upper_case_globals)]
|
|
#[no_mangle]
|
|
pub static mut errno: c_int = 0;
|
|
|
|
#[allow(non_upper_case_globals)]
|
|
pub static mut argv: *mut *mut c_char = ptr::null_mut();
|
|
#[allow(non_upper_case_globals)]
|
|
pub static mut inner_argv: Vec<*mut c_char> = Vec::new();
|
|
|
|
#[allow(non_upper_case_globals)]
|
|
#[no_mangle]
|
|
pub static mut environ: *mut *mut c_char = ptr::null_mut();
|
|
#[allow(non_upper_case_globals)]
|
|
pub static mut inner_environ: Vec<*mut c_char> = Vec::new();
|
|
|
|
pub trait WriteByte: fmt::Write {
|
|
fn write_u8(&mut self, byte: u8) -> fmt::Result;
|
|
}
|
|
|
|
impl<'a, W: WriteByte> WriteByte for &'a mut W {
|
|
fn write_u8(&mut self, byte: u8) -> fmt::Result {
|
|
(**self).write_u8(byte)
|
|
}
|
|
}
|
|
|
|
pub struct FileWriter(pub c_int);
|
|
|
|
impl FileWriter {
|
|
pub fn write(&mut self, buf: &[u8]) -> isize {
|
|
Sys::write(self.0, buf)
|
|
}
|
|
}
|
|
|
|
impl fmt::Write for FileWriter {
|
|
fn write_str(&mut self, s: &str) -> fmt::Result {
|
|
self.write(s.as_bytes());
|
|
Ok(())
|
|
}
|
|
}
|
|
|
|
impl WriteByte for FileWriter {
|
|
fn write_u8(&mut self, byte: u8) -> fmt::Result {
|
|
self.write(&[byte]);
|
|
Ok(())
|
|
}
|
|
}
|
|
|
|
pub struct FileReader(pub c_int);
|
|
|
|
impl FileReader {
|
|
pub fn read(&mut self, buf: &mut [u8]) -> isize {
|
|
Sys::read(self.0, buf)
|
|
}
|
|
}
|
|
|
|
impl Read for FileReader {
|
|
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
|
|
let i = Sys::read(self.0, buf);
|
|
if i >= 0 {
|
|
Ok(i as usize)
|
|
} else {
|
|
Err(io::Error::from_raw_os_error(-i as i32))
|
|
}
|
|
}
|
|
}
|
|
|
|
pub struct AllocStringWriter(pub *mut u8, pub usize);
|
|
impl Write for AllocStringWriter {
|
|
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
|
|
let ptr = unsafe { realloc(self.0 as *mut c_void, self.1 + buf.len() + 1) as *mut u8 };
|
|
if ptr.is_null() {
|
|
return Err(io::Error::new(
|
|
io::ErrorKind::Other,
|
|
"AllocStringWriter::write failed to allocate",
|
|
));
|
|
}
|
|
self.0 = ptr;
|
|
|
|
unsafe {
|
|
ptr::copy_nonoverlapping(buf.as_ptr(), self.0.add(self.1), buf.len());
|
|
self.1 += buf.len();
|
|
*self.0.add(self.1) = 0;
|
|
}
|
|
|
|
Ok(buf.len())
|
|
}
|
|
fn flush(&mut self) -> io::Result<()> {
|
|
Ok(())
|
|
}
|
|
}
|
|
impl fmt::Write for AllocStringWriter {
|
|
fn write_str(&mut self, s: &str) -> fmt::Result {
|
|
// can't fail
|
|
self.write(s.as_bytes()).unwrap();
|
|
Ok(())
|
|
}
|
|
}
|
|
impl WriteByte for AllocStringWriter {
|
|
fn write_u8(&mut self, byte: u8) -> fmt::Result {
|
|
// can't fail
|
|
self.write(&[byte]).unwrap();
|
|
Ok(())
|
|
}
|
|
}
|
|
|
|
pub struct StringWriter(pub *mut u8, pub usize);
|
|
impl Write for StringWriter {
|
|
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
|
|
if self.1 > 1 {
|
|
let copy_size = buf.len().min(self.1 - 1);
|
|
unsafe {
|
|
ptr::copy_nonoverlapping(buf.as_ptr(), self.0, copy_size);
|
|
self.1 -= copy_size;
|
|
|
|
self.0 = self.0.add(copy_size);
|
|
*self.0 = 0;
|
|
}
|
|
|
|
Ok(copy_size)
|
|
} else {
|
|
Ok(0)
|
|
}
|
|
}
|
|
fn flush(&mut self) -> io::Result<()> {
|
|
Ok(())
|
|
}
|
|
}
|
|
impl fmt::Write for StringWriter {
|
|
fn write_str(&mut self, s: &str) -> fmt::Result {
|
|
// can't fail
|
|
self.write(s.as_bytes()).unwrap();
|
|
Ok(())
|
|
}
|
|
}
|
|
impl WriteByte for StringWriter {
|
|
fn write_u8(&mut self, byte: u8) -> fmt::Result {
|
|
// can't fail
|
|
self.write(&[byte]).unwrap();
|
|
Ok(())
|
|
}
|
|
}
|
|
|
|
pub struct UnsafeStringWriter(pub *mut u8);
|
|
impl Write for UnsafeStringWriter {
|
|
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
|
|
unsafe {
|
|
ptr::copy_nonoverlapping(buf.as_ptr(), self.0, buf.len());
|
|
self.0 = self.0.add(buf.len());
|
|
*self.0 = b'\0';
|
|
}
|
|
Ok(buf.len())
|
|
}
|
|
fn flush(&mut self) -> io::Result<()> {
|
|
Ok(())
|
|
}
|
|
}
|
|
impl fmt::Write for UnsafeStringWriter {
|
|
fn write_str(&mut self, s: &str) -> fmt::Result {
|
|
// can't fail
|
|
self.write(s.as_bytes()).unwrap();
|
|
Ok(())
|
|
}
|
|
}
|
|
impl WriteByte for UnsafeStringWriter {
|
|
fn write_u8(&mut self, byte: u8) -> fmt::Result {
|
|
// can't fail
|
|
self.write(&[byte]).unwrap();
|
|
Ok(())
|
|
}
|
|
}
|
|
|
|
pub struct UnsafeStringReader(pub *const u8);
|
|
impl Read for UnsafeStringReader {
|
|
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
|
|
unsafe {
|
|
for i in 0..buf.len() {
|
|
if *self.0 == 0 {
|
|
return Ok(i);
|
|
}
|
|
|
|
buf[i] = *self.0;
|
|
self.0 = self.0.offset(1);
|
|
}
|
|
Ok(buf.len())
|
|
}
|
|
}
|
|
}
|
|
|
|
pub struct CountingWriter<T> {
|
|
pub inner: T,
|
|
pub written: usize,
|
|
}
|
|
impl<T> CountingWriter<T> {
|
|
pub fn new(writer: T) -> Self {
|
|
Self {
|
|
inner: writer,
|
|
written: 0,
|
|
}
|
|
}
|
|
}
|
|
impl<T: fmt::Write> fmt::Write for CountingWriter<T> {
|
|
fn write_str(&mut self, s: &str) -> fmt::Result {
|
|
self.written += s.len();
|
|
self.inner.write_str(s)
|
|
}
|
|
}
|
|
impl<T: WriteByte> WriteByte for CountingWriter<T> {
|
|
fn write_u8(&mut self, byte: u8) -> fmt::Result {
|
|
self.written += 1;
|
|
self.inner.write_u8(byte)
|
|
}
|
|
}
|
|
impl<T: Write> Write for CountingWriter<T> {
|
|
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
|
|
let res = self.inner.write(buf);
|
|
if let Ok(written) = res {
|
|
self.written += written;
|
|
}
|
|
res
|
|
}
|
|
fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
|
|
match self.inner.write_all(&buf) {
|
|
Ok(()) => (),
|
|
Err(ref err) if err.kind() == io::ErrorKind::WriteZero => (),
|
|
Err(err) => return Err(err),
|
|
}
|
|
self.written += buf.len();
|
|
Ok(())
|
|
}
|
|
fn flush(&mut self) -> io::Result<()> {
|
|
self.inner.flush()
|
|
}
|
|
}
|