[project @ 1998-11-26 09:17:22 by sof]
[ghc-hetmet.git] / ghc / lib / std / cbits / flushFile.lc
1 %
2 % (c) The GRASP/AQUA Project, Glasgow University, 1994
3 %
4 \subsection[flushFile.lc]{hFlush Runtime Support}
5
6 Empty contents of output buffers.
7
8 \begin{code}
9
10 #include "rtsdefs.h"
11 #include "stgio.h"
12
13 StgInt
14 flushFile(ptr)
15 StgForeignObj ptr;
16 {
17     IOFileObject* fo = (IOFileObject*)ptr;
18     int rc = 0;
19
20     if ( (fo->flags & FILEOBJ_FLUSH) && !FILEOBJ_BUFFER_EMPTY(fo) ) {
21        rc = writeBuffer(ptr,fo->bufWPtr - fo->bufRPtr);
22     }
23
24     return rc;
25 }
26
27 StgInt
28 flushBuffer(ptr)
29 StgForeignObj ptr;
30 {
31     IOFileObject* fo = (IOFileObject*)ptr;
32     int rc = 0;
33
34     /* If the file object is writeable, or if its
35        RW and the last operation on it was a write,
36        flush it.
37     */
38     if ( (!FILEOBJ_READABLE(fo) && FILEOBJ_WRITEABLE(fo)) || (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 StgForeignObj 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 flushConnectedHandle(ptr)
85 StgForeignObj ptr;
86 {
87     StgInt rc;
88     IOFileObject* fo = (IOFileObject*)ptr;
89
90
91     /* if the stream is connected to an output stream, flush it first */
92     if ( fo->connectedTo != NULL   && fo->connectedTo->fd != -1 &&
93          (fo->connectedTo->flags & FILEOBJ_WRITE)  ) {
94         rc = flushBuffer((StgForeignObj)fo->connectedTo);
95     }
96     /* Willfully ignore return code for now */
97     return;  
98 }
99
100 \end{code}