% % (c) The GRASP/AQUA Project, Glasgow University, 1997 % \subsection[freeFile.lc]{Giving up files} \begin{code} #include "rtsdefs.h" #include "stgio.h" #include "fileObject.h" /* sigh, the FILEs attached to the standard descriptors are handled differently. We don't want them freed via the ForeignObj finaliser, as we probably want to use these before we *really* shut down (dumping stats etc.) */ void freeStdFile(fp) StgForeignObj fp; { return; } void freeStdFileObject(ptr) StgForeignObj ptr; { IOFileObject* fo = (IOFileObject*)ptr; /* Don't close the file, just flush the buffer */ if (fo != NULL && fo->fd != -1) { if (fo->buf != NULL && (fo->flags & FILEOBJ_FLUSH) && fo->bufWPtr > 0) { /* Flush buffer contents */ writeBuffer((StgForeignObj)fo, fo->bufWPtr); } } } void freeFileObject(ptr) StgForeignObj ptr; { /* * The finaliser for the file objects embedded in Handles. The RTS * assumes that the finaliser runs without problems, so all * we can do here is flish buffers + close(), and hope nothing went wrong. * */ int rc; IOFileObject* fo = (IOFileObject*)ptr; if ( fo == NULL ) return; if ( fo->fd == -1 || (rc = unlockFile(fo->fd)) ) { /* If the file handle has been explicitly closed * (via closeFile()), we will have given * up our process lock, so we break off and just return. */ return; } if (fo->buf != NULL && fo->bufWPtr > 0) { /* Flush buffer contents before closing underlying file */ fo->flags &= ~FILEOBJ_RW_WRITE | ~FILEOBJ_RW_READ; flushFile(ptr); } rc = close(fo->fd); /* Error or no error, we don't care.. */ return; } \end{code}