[project @ 1998-12-02 13:17:09 by simonm]
[ghc-hetmet.git] / ghc / lib / std / cbits / fileObject.c
1 /* 
2  * (c) The GRASP/AQUA Project, Glasgow University, 1994-1998
3  *
4  * $Id: fileObject.c,v 1.2 1998/12/02 13:27:26 simonm Exp $
5  *
6  * hPutStr Runtime Support
7  */
8
9 #include "Rts.h"
10 #include "stgio.h"
11 #include "fileObject.h"
12
13 void
14 setBufFlags(fo, flg)
15 StgForeignPtr fo;
16 StgInt flg;
17 {
18   ((IOFileObject*)fo)->flags = flg;
19   return;
20 }
21
22 void
23 setBufWPtr(fo, len)
24 StgForeignPtr fo;
25 StgInt len;
26 {
27   ((IOFileObject*)fo)->bufWPtr = len;
28   return;
29 }
30
31 StgInt
32 getBufWPtr(fo)
33 StgForeignPtr fo;
34 {
35   return (((IOFileObject*)fo)->bufWPtr);
36 }
37
38 StgInt
39 getBufSize(fo)
40 StgForeignPtr fo;
41 {
42   return (((IOFileObject*)fo)->bufSize);
43 }
44
45 void
46 setBuf(fo, buf,sz)
47 StgForeignPtr fo;
48 StgAddr buf;
49 StgInt sz;
50 {
51   ((IOFileObject*)fo)->buf     = buf;
52   ((IOFileObject*)fo)->bufSize = sz;
53   return;
54 }
55
56 StgAddr
57 getBuf(fo)
58 StgForeignPtr fo;
59 { return (((IOFileObject*)fo)->buf); }
60
61 StgAddr
62 getWriteableBuf(ptr)
63 StgForeignPtr ptr;
64
65    /* getWriteableBuf() is called prior to starting to pack
66       a Haskell string into the IOFileObject buffer. It takes
67       care of flushing the (input) buffer in the case we're
68       dealing with a RW handle.
69    */
70    IOFileObject* fo = (IOFileObject*)ptr;
71
72    if ( FILEOBJ_READABLE(fo) && FILEOBJ_JUST_READ(fo) ) {
73       flushReadBuffer(ptr);  /* ignoring return code */
74       /* Ahead of time really, but indicate that we're (just about to) write */
75    }
76    fo->flags = (fo->flags & ~FILEOBJ_RW_READ) | FILEOBJ_RW_WRITE;
77    return (fo->buf);
78 }
79
80 StgAddr
81 getBufStart(fo,count)
82 StgForeignPtr fo;
83 StgInt count;
84 { return ((char*)((IOFileObject*)fo)->buf + (((IOFileObject*)fo)->bufRPtr) - count); }
85
86 StgInt
87 getFileFd(fo)
88 StgForeignPtr fo;
89 { return (((IOFileObject*)fo)->fd); }
90
91 StgInt
92 getConnFileFd(fo)
93 StgForeignPtr fo;
94 { return (((IOFileObject*)fo)->connectedTo->fd); }
95
96
97 void
98 setFd(fo,fp)
99 StgForeignPtr fo;
100 StgInt fp;
101 { ((IOFileObject*)fo)->fd = fp;
102   return;
103 }
104
105 void
106 setConnectedTo(fo, fw, flg)
107 StgForeignPtr fo;
108 StgForeignPtr fw;
109 StgInt flg;
110 {
111   if( flg && (! isatty(((IOFileObject*)fo)->fd) || !isatty(((IOFileObject*)fw)->fd)) ) {
112       return;
113   }
114  ((IOFileObject*)fo)->connectedTo = (IOFileObject*)fw;
115   return;
116 }
117
118 static int __pushback_buf_size__ = 2;
119
120 void
121 setPushbackBufSize(i)
122 StgInt i;
123 { __pushback_buf_size__ = (i > 0 ? i : 0); }
124
125 StgInt
126 getPushbackBufSize()
127 { return (__pushback_buf_size__); }
128
129 void
130 clearNonBlockingIOFlag__ (ptr)
131 StgForeignPtr ptr;
132 { ((IOFileObject*)ptr)->flags &= ~FILEOBJ_NONBLOCKING_IO; }
133
134 void
135 setNonBlockingIOFlag__ (ptr)
136 StgForeignPtr ptr;
137 { ((IOFileObject*)ptr)->flags |= FILEOBJ_NONBLOCKING_IO; }
138
139 void
140 clearConnNonBlockingIOFlag__ (ptr)
141 StgForeignPtr ptr;
142 { ((IOFileObject*)ptr)->connectedTo->flags &= ~FILEOBJ_NONBLOCKING_IO; }
143
144 void
145 setConnNonBlockingIOFlag__ (ptr)
146 StgForeignPtr ptr;
147
148   if ( ((IOFileObject*)ptr)->connectedTo != NULL )  {
149     ((IOFileObject*)ptr)->connectedTo->flags |= FILEOBJ_NONBLOCKING_IO;
150   }
151   return;
152 }
153
154
155 /* Only ever called on line-buffered file objects */
156 StgInt
157 fill_up_line_buffer(fo)
158 IOFileObject* fo;
159 {
160   int count,len, ipos;
161   unsigned char* p;
162
163   /* ToDo: deal with buffer overflow (i.e., realloc buffer if this happens) */
164  
165   if ( fo->bufRPtr == fo->bufWPtr ) { /* There's nothing in the buffer, reset */
166       fo->bufRPtr=0;
167       fo->bufWPtr=0;
168   }
169   ipos = fo->bufWPtr;
170   len = fo->bufSize - fo->bufWPtr + 1;
171   p   = (unsigned char*)fo->buf + fo->bufWPtr;
172
173   if ( fo->flags & FILEOBJ_NONBLOCKING_IO && inputReady ((StgForeignPtr)fo,0) != 1 )
174      return FILEOBJ_BLOCKED_READ;
175
176   if ((count = read(fo->fd, p, len)) <= 0) {
177       if (count == 0) {
178          ghc_errtype = ERR_EOF;
179          ghc_errstr = "";
180          FILEOBJ_SET_EOF(fo);
181          return -1;
182       } else if ( count == -1 && errno == EAGAIN) {
183          errno = 0;
184          return FILEOBJ_BLOCKED_READ;
185       } else if ( count == -1 && errno != EINTR ) {
186          cvtErrno();
187          stdErrno();
188          return -1;
189       }
190   }
191   fo->bufWPtr += count;
192   return (fo->bufWPtr - ipos);
193 }