use crate::{self as libc, errno, string}; use core::fmt; use core::ops::{Deref, DerefMut}; pub struct Error { pub errno: errno::Errno, } impl From for fmt::Error { fn from(_err: Error) -> fmt::Error { fmt::Error } } pub type Result = core::result::Result; #[inline] fn check_io(ok: bool) -> Result<()> { if ok { Ok(()) } else { Err(Error { errno: errno::errno(), }) } } pub struct BasicOStream(*mut libc::FILE); unsafe impl Sync for BasicOStream {} unsafe impl Send for BasicOStream {} pub type Stdout = BasicOStream; pub type Stderr = BasicOStream; #[inline] pub fn stdout() -> Stdout { BasicOStream(unsafe { libc::stdout }) } #[inline] pub fn stderr() -> Stderr { BasicOStream(unsafe { libc::stderr }) } impl BasicOStream { #[inline] pub fn flush(&mut self) -> Result<()> { check_io(unsafe { libc::fflush(self.0) } == 0) } #[inline] pub fn write(&mut self, b: &[u8]) -> Result<()> { check_io(unsafe { libc::fwrite(b.as_ptr().cast(), 1, b.len(), self.0) } == b.len()) } #[inline] pub fn puts(&mut self, s: &string::CStr) -> Result<()> { check_io(unsafe { libc::fputs(s.as_ptr(), self.0) } != libc::EOF) } } impl fmt::Write for BasicOStream { #[inline] fn write_str(&mut self, s: &str) -> fmt::Result { self.write(s.as_bytes())?; Ok(()) } } pub struct OStream(BasicOStream); impl OStream { #[inline] pub unsafe fn from_raw(file: *mut libc::FILE) -> OStream { OStream(BasicOStream(file)) } } impl Drop for OStream { #[inline] fn drop(&mut self) { unsafe { libc::fclose((self.0).0); } } } impl Deref for OStream { type Target = BasicOStream; #[inline] fn deref(&self) -> &BasicOStream { &self.0 } } impl DerefMut for OStream { #[inline] fn deref_mut(&mut self) -> &mut BasicOStream { &mut self.0 } }