[project @ 1999-11-26 16:25:55 by simonmar]
[ghc-hetmet.git] / ghc / lib / std / cbits / freeFile.c
1 /* 
2  * (c) The GRASP/AQUA Project, Glasgow University, 1994-1998
3  *
4  * $Id: freeFile.c,v 1.8 1999/11/26 16:25:56 simonmar Exp $
5  *
6  * Giving up files
7  */
8
9 #include "Rts.h"
10 #include "stgio.h"
11
12 #if defined(HAVE_WINSOCK_H) && !defined(__CYGWIN__) && !defined(__CYGWIN32__)
13 #define USE_WINSOCK
14 #endif
15
16 #ifdef USE_WINSOCK
17 #include <winsock.h>
18 #endif
19
20
21 /* sigh, the FILEs attached to the standard descriptors are 
22    handled differently. We don't want them freed via the
23    ForeignObj finaliser, as we probably want to use these
24    before we *really* shut down (dumping stats etc.)
25 */
26 void
27 freeStdFile(StgForeignPtr fp)
28 { return; }
29
30 void
31 freeStdFileObject(StgForeignPtr ptr)
32
33   IOFileObject* fo = (IOFileObject*)ptr;
34   int rc;
35
36   /* Don't close the file, just flush the buffer */
37   if (fo != NULL && fo->fd != -1) {
38     if (fo->buf != NULL && (fo->flags & FILEOBJ_WRITE) && fo->bufWPtr > 0) {
39        /* Flush buffer contents */
40        do {
41          rc = writeBuffer((StgForeignPtr)fo, fo->bufWPtr);
42        } while (rc == FILEOBJ_BLOCKED_WRITE) ;
43     }
44   }
45 }
46
47 void
48 freeFileObject(StgForeignPtr ptr)
49 {
50     /*
51      * The finaliser for the file objects embedded in Handles. The RTS
52      * assumes that the finaliser runs without problems, so all
53      * we can do here is flish buffers + close(), and hope nothing went wrong.
54      *
55      */
56
57     int rc;
58     IOFileObject* fo = (IOFileObject*)ptr;
59
60     if ( fo == NULL )
61       return;
62
63     if ( fo->fd == -1 || (rc = unlockFile(fo->fd)) ) {
64         /* If the file handle has been explicitly closed
65          * (via closeFile()), we will have given
66          * up our process lock, so we break off and just return.
67          */
68        return;
69     }
70
71     if (fo->buf != NULL && fo->bufWPtr > 0) {
72        /* Flush buffer contents before closing underlying file */
73        fo->flags &= ~FILEOBJ_RW_WRITE | ~FILEOBJ_RW_READ;
74        flushFile(ptr);
75     }
76
77 #ifdef USE_WINSOCK
78     if ( fo->flags & FILEOBJ_WINSOCK )
79       /* Sigh - the cleanup call at the end will do this for us */
80       return;
81     rc = ( fo->flags & FILEOBJ_WINSOCK ? closesocket(fo->fd) : close(fo->fd) );
82 #else
83     rc = close(fo->fd);
84 #endif
85     /* Error or no error, we don't care.. */
86
87     return;
88 }
89
90 StgAddr
91 ref_freeStdFileObject(void)
92 {
93     return (StgAddr)&freeStdFileObject;
94 }
95
96 StgAddr
97 ref_freeFileObject(void)
98 {
99     return (StgAddr)&freeFileObject;
100 }
101