[project @ 2000-04-12 17:33:16 by simonmar]
[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.7 2000/04/12 17:33:16 simonmar Exp $
5  *
6  * hFlush Runtime Support
7  */
8
9 #include "Rts.h"
10 #include "stgio.h"
11
12 StgInt
13 flushFile(StgForeignPtr ptr)
14 {
15     IOFileObject* fo = (IOFileObject*)ptr;
16     int rc = 0;
17
18     if ( (fo->flags & FILEOBJ_WRITE) && FILEOBJ_NEEDS_FLUSHING(fo) ) {
19        rc = writeBuffer(ptr,fo->bufWPtr - fo->bufRPtr);
20     }
21
22     return rc;
23 }
24
25 StgInt
26 flushBuffer(StgForeignPtr ptr)
27 {
28     IOFileObject* fo = (IOFileObject*)ptr;
29     int rc = 0;
30
31     /* If the file object is writeable, or if it's
32        RW *and* the last operation on it was a write,
33        flush it.
34     */
35     if ( (!FILEOBJ_READABLE(fo) && FILEOBJ_WRITEABLE(fo)) ||
36          (FILEOBJ_RW(fo) && FILEOBJ_JUST_WRITTEN(fo)) ) {
37        rc = flushFile(ptr);
38        if (rc<0) return rc;
39     }
40     
41     /* TODO: shouldn't we do the lseek stuff from flushReadBuffer
42      * here???? --SDM
43      */
44
45     /* Reset read & write pointer for input buffers */
46     if ( (fo->flags & FILEOBJ_READ) ) {
47        fo->bufRPtr=0;
48        fo->bufWPtr=0;
49     }
50     return 0;
51 }
52
53 /*
54  For RW file objects, flushing input buffers doesn't just involve 
55  resetting the read & write pointers, we also have to change the
56  underlying file position to point to the effective read position.
57
58  (Sigh, I now understand the real reason for why stdio opted for
59  the solution of leaving this to the programmer!)
60 */
61 StgInt
62 flushReadBuffer(StgForeignPtr ptr)
63 {
64     IOFileObject* fo = (IOFileObject*)ptr;
65     int delta;
66
67     delta = fo->bufWPtr - fo->bufRPtr;
68
69     if ( delta > 0 ) {
70        while ( lseek(fo->fd, -delta, SEEK_CUR) == -1) {
71           if (errno != EINTR) {
72              cvtErrno();
73              stdErrno();
74              return -1;
75           }
76        }
77     }
78
79     fo->bufRPtr=0;
80     fo->bufWPtr=0;
81     return 0;
82 }
83
84 void
85 flushConnectedBuf(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