[project @ 2000-09-25 10:51:04 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.8 2000/09/25 10:51:04 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 ( FILEOBJ_WRITEABLE(fo) && FILEOBJ_JUST_WRITTEN(fo) &&
19          FILEOBJ_NEEDS_FLUSHING(fo) ) {
20        rc = writeBuffer(ptr, fo->bufWPtr - fo->bufRPtr);
21     }
22
23     return rc;
24 }
25
26 StgInt
27 flushBuffer(StgForeignPtr ptr)
28 {
29     IOFileObject* fo = (IOFileObject*)ptr;
30     int rc = 0;
31
32     if ( FILEOBJ_WRITEABLE(fo) && FILEOBJ_JUST_WRITTEN(fo) &&
33          FILEOBJ_NEEDS_FLUSHING(fo) ) {
34         rc = writeBuffer(ptr, fo->bufWPtr - fo->bufRPtr);
35         if (rc<0) return rc;
36     }
37     
38     /* TODO: shouldn't we do the lseek stuff from flushReadBuffer
39      * here???? --SDM
40      */
41
42     /* Reset read & write pointer for input buffers */
43     if ( (fo->flags & FILEOBJ_READ) ) {
44        fo->bufRPtr=0;
45        fo->bufWPtr=0;
46     }
47     return 0;
48 }
49
50 /*
51  For RW file objects, flushing input buffers doesn't just involve 
52  resetting the read & write pointers, we also have to change the
53  underlying file position to point to the effective read position.
54
55  (Sigh, I now understand the real reason for why stdio opted for
56  the solution of leaving this to the programmer!)
57 */
58 StgInt
59 flushReadBuffer(StgForeignPtr ptr)
60 {
61     IOFileObject* fo = (IOFileObject*)ptr;
62     int delta;
63
64     delta = fo->bufWPtr - fo->bufRPtr;
65
66     if ( delta > 0 ) {
67        while ( lseek(fo->fd, -delta, SEEK_CUR) == -1) {
68           if (errno != EINTR) {
69              cvtErrno();
70              stdErrno();
71              return -1;
72           }
73        }
74     }
75
76     fo->bufRPtr=0;
77     fo->bufWPtr=0;
78     return 0;
79 }
80
81 void
82 flushConnectedBuf(StgForeignPtr ptr)
83 {
84     StgInt rc;
85     IOFileObject* fo = (IOFileObject*)ptr;
86     
87     /* if the stream is connected to an output stream, flush it. */
88     if ( fo->connectedTo != NULL && fo->connectedTo->fd != -1 &&
89          (fo->connectedTo->flags & FILEOBJ_WRITE) ) {
90        rc = flushBuffer((StgForeignPtr)fo->connectedTo);
91     }
92     /* Willfully ignore the return code for now. */
93     return;
94 }
95
96