[project @ 2000-04-12 17:12:23 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.6 1999/11/25 16:54:14 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     /* Reset read & write pointer for input buffers */
42     if ( (fo->flags & FILEOBJ_READ) ) {
43        fo->bufRPtr=0;
44        fo->bufWPtr=0;
45     }
46     return 0;
47 }
48
49 /*
50  For RW file objects, flushing input buffers doesn't just involve 
51  resetting the read & write pointers, we also have to change the
52  underlying file position to point to the effective read position.
53
54  (Sigh, I now understand the real reason for why stdio opted for
55  the solution of leaving this to the programmer!)
56 */
57 StgInt
58 flushReadBuffer(StgForeignPtr ptr)
59 {
60     IOFileObject* fo = (IOFileObject*)ptr;
61     int delta;
62
63     delta = fo->bufWPtr - fo->bufRPtr;
64
65     if ( delta > 0 ) {
66        while ( lseek(fo->fd, -delta, SEEK_CUR) == -1) {
67           if (errno != EINTR) {
68              cvtErrno();
69              stdErrno();
70              return -1;
71           }
72        }
73     }
74
75     fo->bufRPtr=0;
76     fo->bufWPtr=0;
77     return 0;
78 }
79
80 void
81 flushConnectedBuf(StgForeignPtr ptr)
82 {
83     StgInt rc;
84     IOFileObject* fo = (IOFileObject*)ptr;
85     
86     /* if the stream is connected to an output stream, flush it. */
87     if ( fo->connectedTo != NULL && fo->connectedTo->fd != -1 &&
88          (fo->connectedTo->flags & FILEOBJ_WRITE) ) {
89        rc = flushBuffer((StgForeignPtr)fo->connectedTo);
90     }
91     /* Willfully ignore the return code for now. */
92     return;
93 }
94
95