diff --git a/src/stdio/src/lib.rs b/src/stdio/src/lib.rs
index 1d720ed7e1423be584081e1708ec3b3d082926ac..4c00df7c2cf20d1e0c8dd6f91e7bf0a1ceba63fa 100644
--- a/src/stdio/src/lib.rs
+++ b/src/stdio/src/lib.rs
@@ -142,7 +142,11 @@ impl FILE {
         unreachable!()
     }
     pub fn read(&mut self, buf: &mut [u8]) -> usize {
-        let adj = !(self.buf.len() == 0) as usize;
+        let adj = if self.buf.len() > 0 {
+            0
+        } else {
+            1
+        };
         let mut file_buf = &mut self.buf[self.unget..];
         let count = if buf.len() <= 1 + adj {
             platform::read(self.fd, &mut file_buf)
@@ -320,15 +324,14 @@ pub extern "C" fn fgetpos(stream: &mut FILE, pos: Option<&mut fpos_t>) -> c_int
 /// Get a string from the stream
 #[no_mangle]
 pub extern "C" fn fgets(s: *mut c_char, n: c_int, stream: &mut FILE) -> *mut c_char {
-    use platform::c_str_n_mut;
-
+    use core::slice;
     flockfile(stream);
-    let st = unsafe { c_str_n_mut(s, n as usize) };
+    let st = unsafe { slice::from_raw_parts_mut(s, n as usize) };
 
     // We can only fit one or less chars in
     if n <= 1 {
         funlockfile(stream);
-        if n == 0 {
+        if n <= 0 {
             return ptr::null_mut();
         }
         unsafe {
@@ -344,21 +347,35 @@ pub extern "C" fn fgets(s: *mut c_char, n: c_int, stream: &mut FILE) -> *mut c_c
         }
     }
 
+    let mut diff = 0;
     if let Some((rpos, rend)) = stream.read {
-        let mut diff = 0;
-        for (_, mut c) in stream.buf[rpos..rend]
-            .iter()
-            .enumerate()
-            .take_while(|&(i, c)| *c != b'\n' && i < n as usize)
-        {
-            st[diff] = *c;
+        for _ in (0..(n-1) as usize).take_while(|x| rpos + x < rend) {
+            st[diff] = stream.buf[rpos + diff] as i8;
             diff += 1;
         }
-        stream.read = Some((rpos + diff, rend));
-    } else {
-        return ptr::null_mut();
+        stream.read = Some((rpos+diff, rend));
+        for i in diff..(n-1) as usize {
+            let mut c = [0u8];
+            let d = stream.read(&mut c);
+            if d != 1 {
+                if diff == 0 {
+                    return ptr::null_mut();
+                } else {
+                    break;
+                }
+            }
+            if c[0] as i8 == -1 {
+                break;
+            }
+            st[i] = c[0] as i8;
+            diff += 1;
+            if c[0] == b'\n' || c[0] as i8 == stream.buf_char {
+                break;
+            }
+        }
     }
 
+    st[diff] = 0;
     funlockfile(stream);
     s
 }