summaryrefslogtreecommitdiffstats
path: root/safe_libc/src/stdio.rs
diff options
context:
space:
mode:
Diffstat (limited to 'safe_libc/src/stdio.rs')
-rw-r--r--safe_libc/src/stdio.rs102
1 files changed, 83 insertions, 19 deletions
diff --git a/safe_libc/src/stdio.rs b/safe_libc/src/stdio.rs
index 271f023..2d19725 100644
--- a/safe_libc/src/stdio.rs
+++ b/safe_libc/src/stdio.rs
@@ -1,47 +1,111 @@
-use crate as libc;
-use crate::string;
+use crate::{self as libc, errno, string};
use core::fmt;
+use core::ops::{Deref, DerefMut};
-pub struct OStream {
- file: *mut libc::FILE
+pub struct Error {
+ pub errno: errno::Errno,
}
+pub type Result<T> = core::result::Result<T, Error>;
+
+#[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 unsafe fn stdout() -> OStream {
- OStream { file: libc::stdout }
+pub fn stdout() -> Stdout {
+ BasicOStream(unsafe { libc::stdout })
}
#[inline]
-pub unsafe fn stderr() -> OStream {
- OStream { file: libc::stderr }
+pub fn stderr() -> Stderr {
+ BasicOStream(unsafe { libc::stderr })
}
-impl OStream {
+impl BasicOStream {
#[inline]
- pub fn write(&mut self, b: &[u8]) {
- unsafe {
+ 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.file,
- );
+ 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 {
+ if self.write(s.as_bytes()).is_err() {
+ return Err(fmt::Error);
}
+ 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]
- pub fn puts(&mut self, s: &string::CStr) {
+ fn drop(&mut self) {
unsafe {
- libc::fputs(s.as_ptr(), self.file);
+ libc::fclose((self.0).0);
}
}
}
-impl fmt::Write for OStream {
+impl Deref for OStream {
+ type Target = BasicOStream;
+
#[inline]
- fn write_str(&mut self, s: &str) -> fmt::Result {
- self.write(s.as_bytes());
- Ok(())
+ fn deref(&self) -> &BasicOStream {
+ &self.0
+ }
+}
+
+impl DerefMut for OStream {
+ #[inline]
+ fn deref_mut(&mut self) -> &mut BasicOStream {
+ &mut self.0
}
}