summaryrefslogtreecommitdiff
path: root/ghc/lib/std/cbits/flushFile.c
diff options
context:
space:
mode:
authorsimonm <unknown>1998-12-02 13:32:30 +0000
committersimonm <unknown>1998-12-02 13:32:30 +0000
commit438596897ebbe25a07e1c82085cfbc5bdb00f09e (patch)
treeda7a441396aed2e13f6e0cc55282bf041b0cf72c /ghc/lib/std/cbits/flushFile.c
parent967cc47f37cb93a5e2b6df7822c9a646f0428247 (diff)
downloadhaskell-438596897ebbe25a07e1c82085cfbc5bdb00f09e.tar.gz
[project @ 1998-12-02 13:17:09 by simonm]
Move 4.01 onto the main trunk.
Diffstat (limited to 'ghc/lib/std/cbits/flushFile.c')
-rw-r--r--ghc/lib/std/cbits/flushFile.c80
1 files changed, 80 insertions, 0 deletions
diff --git a/ghc/lib/std/cbits/flushFile.c b/ghc/lib/std/cbits/flushFile.c
new file mode 100644
index 0000000000..7390b27ec2
--- /dev/null
+++ b/ghc/lib/std/cbits/flushFile.c
@@ -0,0 +1,80 @@
+/*
+ * (c) The GRASP/AQUA Project, Glasgow University, 1994-1998
+ *
+ * $Id: flushFile.c,v 1.3 1998/12/02 13:27:32 simonm Exp $
+ *
+ * hFlush Runtime Support
+ */
+
+#include "Rts.h"
+#include "stgio.h"
+
+StgInt
+flushFile(ptr)
+StgForeignPtr ptr;
+{
+ IOFileObject* fo = (IOFileObject*)ptr;
+ int rc = 0;
+
+ if ( (fo->flags & FILEOBJ_FLUSH) && !FILEOBJ_BUFFER_EMPTY(fo) ) {
+ rc = writeBuffer(ptr,fo->bufWPtr - fo->bufRPtr);
+ }
+
+ return rc;
+}
+
+StgInt
+flushBuffer(ptr)
+StgForeignPtr ptr;
+{
+ IOFileObject* fo = (IOFileObject*)ptr;
+ int rc = 0;
+
+ /* If the file object is writeable, or if its
+ RW and the last operation on it was a write,
+ flush it.
+ */
+ if ( (!FILEOBJ_READABLE(fo) && FILEOBJ_WRITEABLE(fo)) || (FILEOBJ_RW(fo) && FILEOBJ_JUST_WRITTEN(fo)) ) {
+ rc = flushFile(ptr);
+ if (rc<0) return rc;
+ }
+
+ /* Reset read & write pointer for input buffers */
+ if ( (fo->flags & FILEOBJ_READ) ) {
+ fo->bufRPtr=0;
+ fo->bufWPtr=0;
+ }
+ return 0;
+}
+
+/*
+ For RW file objects, flushing input buffers doesn't just involve
+ resetting the read & write pointers, we also have to change the
+ underlying file position to point to the effective read position.
+
+ (Sigh, I now understand the real reason for why stdio opted for
+ the solution of leaving this to the programmer!)
+*/
+StgInt
+flushReadBuffer(ptr)
+StgForeignPtr ptr;
+{
+ IOFileObject* fo = (IOFileObject*)ptr;
+ int delta;
+
+ delta = fo->bufWPtr - fo->bufRPtr;
+
+ if ( delta > 0 ) {
+ while ( lseek(fo->fd, -delta, SEEK_CUR) == -1) {
+ if (errno != EINTR) {
+ cvtErrno();
+ stdErrno();
+ return -1;
+ }
+ }
+ }
+
+ fo->bufRPtr=0;
+ fo->bufWPtr=0;
+ return 0;
+}