[project @ 1999-09-19 19:26:14 by sof]
[ghc-hetmet.git] / ghc / lib / std / cbits / flushFile.c
1 /* 
2  * (c) The GRASP/AQUA Project, Glasgow University, 1994-1998
3  *
4  * $Id: flushFile.c,v 1.5 1999/09/19 19:26:14 sof Exp $
5  *
6  * hFlush Runtime Support
7  */
8
9 #include "Rts.h"
10 #include "stgio.h"
11
12 StgInt
13 flushFile(ptr)
14 StgForeignPtr ptr;
15 {
16     IOFileObject* fo = (IOFileObject*)ptr;
17     int rc = 0;
18
19     if ( (fo->flags & FILEOBJ_FLUSH) && FILEOBJ_NEEDS_FLUSHING(fo) ) {
20        rc = writeBuffer(ptr,fo->bufWPtr - fo->bufRPtr);
21     }
22
23     return rc;
24 }
25
26 StgInt
27 flushBuffer(ptr)
28 StgForeignPtr ptr;
29 {
30     IOFileObject* fo = (IOFileObject*)ptr;
31     int rc = 0;
32
33     /* If the file object is writeable, or if it's
34        RW *and* the last operation on it was a write,
35        flush it.
36     */
37     if ( (!FILEOBJ_READABLE(fo) && FILEOBJ_WRITEABLE(fo)) ||
38          (FILEOBJ_RW(fo) && FILEOBJ_JUST_WRITTEN(fo)) ) {
39        rc = flushFile(ptr);
40        if (rc<0) return rc;
41     }
42     
43     /* Reset read & write pointer for input buffers */
44     if ( (fo->flags & FILEOBJ_READ) ) {
45        fo->bufRPtr=0;
46        fo->bufWPtr=0;
47     }
48     return 0;
49 }
50
51 /*
52  For RW file objects, flushing input buffers doesn't just involve 
53  resetting the read & write pointers, we also have to change the
54  underlying file position to point to the effective read position.
55
56  (Sigh, I now understand the real reason for why stdio opted for
57  the solution of leaving this to the programmer!)
58 */
59 StgInt
60 flushReadBuffer(ptr)
61 StgForeignPtr ptr;
62 {
63     IOFileObject* fo = (IOFileObject*)ptr;
64     int delta;
65
66     delta = fo->bufWPtr - fo->bufRPtr;
67
68     if ( delta > 0 ) {
69        while ( lseek(fo->fd, -delta, SEEK_CUR) == -1) {
70           if (errno != EINTR) {
71              cvtErrno();
72              stdErrno();
73              return -1;
74           }
75        }
76     }
77
78     fo->bufRPtr=0;
79     fo->bufWPtr=0;
80     return 0;
81 }
82
83 void
84 flushConnectedBuf(ptr)
85 StgForeignPtr ptr;
86 {
87     StgInt rc;
88     IOFileObject* fo = (IOFileObject*)ptr;
89     
90     /* if the stream is connected to an output stream, flush it. */
91     if ( fo->connectedTo != NULL && fo->connectedTo->fd != -1 &&
92          (fo->connectedTo->flags & FILEOBJ_WRITE) ) {
93        rc = flushBuffer((StgForeignPtr)fo->connectedTo);
94     }
95     /* Willfully ignore the return code for now. */
96     return;
97 }
98
99