From 77b160c70d5c03ad9ba66107a4ecd0dc3db0403f Mon Sep 17 00:00:00 2001
From: Tom Almeida <tommoa256@gmail.com>
Date: Thu, 21 Jun 2018 09:33:21 +0800
Subject: [PATCH] Fixed some issues with temporary files and moved some raw
 pointers to Option<&T>s

---
 src/stdio/src/helpers.rs | 28 ++++++++++++++++-----------
 src/stdio/src/lib.rs     | 41 +++++++++++++++++++++-------------------
 2 files changed, 39 insertions(+), 30 deletions(-)

diff --git a/src/stdio/src/helpers.rs b/src/stdio/src/helpers.rs
index d67050920..242e83f1e 100644
--- a/src/stdio/src/helpers.rs
+++ b/src/stdio/src/helpers.rs
@@ -36,8 +36,10 @@ pub unsafe fn parse_mode_flags(mode_str: *const c_char) -> i32 {
 }
 
 /// Open a file with the file descriptor `fd` in the mode `mode`
-pub unsafe fn _fdopen(fd: c_int, mode: *const c_char) -> Option<FILE> {
+pub unsafe fn _fdopen(fd: c_int, mode: *const c_char) -> Option<*mut FILE> {
     use string::strchr;
+    use stdlib::malloc;
+    use core::mem::size_of;
     if *mode != b'r' as i8 && *mode != b'w' as i8 && *mode != b'a' as i8 {
         platform::errno = errno::EINVAL;
         return None;
@@ -61,16 +63,20 @@ pub unsafe fn _fdopen(fd: c_int, mode: *const c_char) -> Option<FILE> {
     }
 
     // Allocate the file
-    Some(FILE {
-        flags: flags,
-        read: None,
-        write: None,
-        fd: fd,
-        buf: vec![0u8; BUFSIZ + UNGET],
-        buf_char: -1,
-        unget: UNGET,
-        lock: AtomicBool::new(false),
-    })
+    let f = malloc(size_of::<FILE>()) as *mut FILE;
+    if f.is_null() {
+        None
+    } else {
+        (*f).flags = flags;
+        (*f).read = None;
+        (*f).write = None;
+        (*f).fd = fd;
+        (*f).buf = vec![0u8; BUFSIZ + UNGET];
+        (*f).buf_char = -1;
+        (*f).unget = UNGET;
+        (*f).lock = AtomicBool::new(false);
+        Some(f)
+    }
 }
 
 /// Write buffer `buf` of length `l` into `stream`
diff --git a/src/stdio/src/lib.rs b/src/stdio/src/lib.rs
index bc113fefc..8ddb27d4d 100644
--- a/src/stdio/src/lib.rs
+++ b/src/stdio/src/lib.rs
@@ -46,14 +46,14 @@ mod internal;
 /// This struct gets exposed to the C API.
 ///
 pub struct FILE {
-    flags: i32,
-    read: Option<(usize, usize)>,
-    write: Option<(usize, usize, usize)>,
-    fd: c_int,
-    buf: Vec<u8>,
+    flags:    i32,
+    read:     Option<(usize, usize)>,
+    write:    Option<(usize, usize, usize)>,
+    fd:       c_int,
+    buf:      Vec<u8>,
     buf_char: i8,
-    lock: AtomicBool,
-    unget: usize,
+    lock:     AtomicBool,
+    unget:    usize,
 }
 
 impl FILE {
@@ -215,6 +215,8 @@ pub extern "C" fn fclose(stream: &mut FILE) -> c_int {
         unsafe {
             free(stream as *mut _ as *mut _);
         }
+    } else {
+        funlockfile(stream);
     }
     r
 }
@@ -223,8 +225,8 @@ pub extern "C" fn fclose(stream: &mut FILE) -> c_int {
 #[no_mangle]
 pub extern "C" fn fdopen(fildes: c_int, mode: *const c_char) -> *mut FILE {
     use core::ptr;
-    if let Some(mut f) = unsafe { helpers::_fdopen(fildes, mode) } {
-        &mut f
+    if let Some(f) = unsafe { helpers::_fdopen(fildes, mode) } {
+        f
     } else {
         ptr::null_mut()
     }
@@ -272,15 +274,17 @@ pub extern "C" fn fgetc(stream: &mut FILE) -> c_int {
 
 /// Get the position of the stream and store it in pos
 #[no_mangle]
-pub extern "C" fn fgetpos(stream: &mut FILE, pos: *mut fpos_t) -> c_int {
+pub extern "C" fn fgetpos(stream: &mut FILE, pos: Option<&mut fpos_t>) -> c_int {
     let off = internal::ftello(stream);
     if off < 0 {
         return -1;
     }
-    unsafe {
-        (*pos) = off;
+    if let Some(pos) = pos {
+        *pos = off;
+        0
+    } else {
+        -1
     }
-    0
 }
 
 /// Get a string from the stream
@@ -366,12 +370,11 @@ pub extern "C" fn fopen(filename: *const c_char, mode: *const c_char) -> *mut FI
         fcntl::sys_fcntl(fd, fcntl::F_SETFD, fcntl::FD_CLOEXEC);
     }
 
-    let f = unsafe { helpers::_fdopen(fd, mode) };
-    if let Some(mut fi) = f {
-        &mut fi
+    if let Some(f) = unsafe { helpers::_fdopen(fd, mode) } {
+        f
     } else {
         platform::close(fd);
-        return ptr::null_mut();
+        ptr::null_mut()
     }
 }
 
@@ -534,8 +537,8 @@ pub extern "C" fn fseeko(stream: &mut FILE, offset: off_t, whence: c_int) -> c_i
 
 /// Seek to a position `pos` in the file from the beginning of the file
 #[no_mangle]
-pub unsafe extern "C" fn fsetpos(stream: &mut FILE, pos: *const fpos_t) -> c_int {
-    fseek(stream, *pos as off_t, SEEK_SET)
+pub unsafe extern "C" fn fsetpos(stream: &mut FILE, pos: Option<&fpos_t>) -> c_int {
+    fseek(stream, *pos.expect("You must specify a valid position"), SEEK_SET)
 }
 
 /// Get the current position of the cursor in the file
-- 
GitLab