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