summaryrefslogtreecommitdiff
path: root/ghc/lib/std/cbits/flushFile.lc
diff options
context:
space:
mode:
authorsof <unknown>1998-08-14 12:42:23 +0000
committersof <unknown>1998-08-14 12:42:23 +0000
commitbf64fa7057773902012e3cbea5186bc06b94be0b (patch)
treef7b8f34ac5604f7027a33a2d5901ffb97b32c35e /ghc/lib/std/cbits/flushFile.lc
parentfb49b1af911ded218b3b3a84c784be2542c53e86 (diff)
downloadhaskell-bf64fa7057773902012e3cbea5186bc06b94be0b.tar.gz
[project @ 1998-08-14 12:42:01 by sof]
Beefed up IO stub functions to not have to rely on stdio any longer
Diffstat (limited to 'ghc/lib/std/cbits/flushFile.lc')
-rw-r--r--ghc/lib/std/cbits/flushFile.lc77
1 files changed, 67 insertions, 10 deletions
diff --git a/ghc/lib/std/cbits/flushFile.lc b/ghc/lib/std/cbits/flushFile.lc
index 6cfd484e74..595dfc01ac 100644
--- a/ghc/lib/std/cbits/flushFile.lc
+++ b/ghc/lib/std/cbits/flushFile.lc
@@ -3,27 +3,84 @@
%
\subsection[flushFile.lc]{hFlush Runtime Support}
+Empty contents of output buffers.
+
\begin{code}
#include "rtsdefs.h"
#include "stgio.h"
StgInt
-flushFile(fp)
-StgForeignObj fp;
+flushFile(ptr)
+StgForeignObj ptr;
{
- int rc;
-
- while ((rc = fflush((FILE *) fp)) != 0) {
- if (errno != EINTR) {
- cvtErrno();
- stdErrno();
- return rc;
- }
+ 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)
+StgForeignObj 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)
+StgForeignObj 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;
+}
+
+
\end{code}