[project @ 2001-05-18 14:18:34 by simonmar]
[ghc-hetmet.git] / ghc / lib / std / cbits / closeFile.c
index 7f4d818..82fdc51 100644 (file)
@@ -1,20 +1,27 @@
 /* 
  * (c) The GRASP/AQUA Project, Glasgow University, 1994-1998
  *
- * $Id: closeFile.c,v 1.3 1998/12/02 13:27:14 simonm Exp $
+ * $Id: closeFile.c,v 1.10 2000/09/25 10:48:50 simonmar Exp $
  *
  * hClose Runtime Support
  */
 
 #include "Rts.h"
 #include "stgio.h"
+#include <errno.h>
+
+#if defined(HAVE_WINSOCK_H) && !defined(__CYGWIN__) && !defined(__CYGWIN32__)
+#define USE_WINSOCK
+#endif
+
+#ifdef USE_WINSOCK
+#include <winsock.h>
+#endif
 
 StgInt __really_close_stdfiles=1;
 
 StgInt
-closeFile(ptr,flush_buf)
-StgForeignPtr ptr;
-StgInt flush_buf;
+closeFile(StgForeignPtr ptr, StgInt flush_buf)
 {
     IOFileObject* fo = (IOFileObject*)ptr;
     int rc = 0;
@@ -25,8 +32,9 @@ StgInt flush_buf;
        return 0;
     }
 
-    if ( flush_buf != 0 && (fo->flags & FILEOBJ_FLUSH) ) {
-       writeFileObject(ptr,fo->bufWPtr);
+    /* Flush buffer if we have unwritten data */
+    if ( flush_buf != 0 ) {
+       flushBuffer(fo);
     }
 
     /* If the flush failed, we ignore this and soldier on.. */
@@ -53,6 +61,14 @@ StgInt flush_buf;
        
     }
 
+    /* Free the buffer straight away.  We can't free the file object
+     * itself until the finalizer runs.
+     */
+    if ( fo->buf != NULL ) {
+       free(fo->buf);
+       fo->buf = NULL;
+    }
+
     /* Closing file descriptors that refer to standard channels
        is problematic, so we back off from doing this by default,
        just closing them at the Handle level. If you insist on
@@ -64,7 +80,15 @@ StgInt flush_buf;
 
     } else  {
       /* Regardless of success or otherwise, the fd field gets smashed. */
-      while ( (rc = close(fo->fd)) != 0 ) {
+      while ( (rc = 
+               (
+#ifdef USE_WINSOCK
+                 fo->flags & FILEOBJ_WINSOCK ?
+                 closesocket(fo->fd) :
+                  close(fo->fd))) != 0 ) {
+#else
+                  close(fo->fd))) != 0 ) {
+#endif
          /* See above unlockFile() comment */
         if ( errno != EINTR && (!unlocked && errno != EBADF ) ) {
            cvtErrno();
@@ -74,6 +98,8 @@ StgInt flush_buf;
        }
       }
     }
+
     fo->fd = -1;
+
     return 0;
 }