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, PalSignal, PalSocket}; mod pal; pub use self::sys::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; pub use self::rlb::{Line, RawLineBuffer}; pub mod rlb; use self::types::*; pub mod types; //TODO #[thread_local] #[allow(non_upper_case_globals)] #[no_mangle] pub static mut errno: c_int = 0; #[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 { 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 StringWriter(pub *mut u8, pub usize); impl Write for StringWriter { fn write(&mut self, buf: &[u8]) -> io::Result { 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 { 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 { 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 { pub inner: T, pub written: usize, } impl CountingWriter { pub fn new(writer: T) -> Self { Self { inner: writer, written: 0, } } } impl fmt::Write for CountingWriter { fn write_str(&mut self, s: &str) -> fmt::Result { self.written += s.len(); self.inner.write_str(s) } } impl WriteByte for CountingWriter { fn write_u8(&mut self, byte: u8) -> fmt::Result { self.written += 1; self.inner.write_u8(byte) } } impl Write for CountingWriter { fn write(&mut self, buf: &[u8]) -> io::Result { 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() } }