2 * (c) The GRASP/AQUA Project, Glasgow University, 1994-1998
4 * $Id: readFile.c,v 1.3 1998/12/02 13:27:45 simonm Exp $
6 * hGetContents Runtime Support
14 /* Filling up a (block-buffered) buffer, that
15 is completely empty. */
20 IOFileObject* fo = (IOFileObject*)ptr;
24 /* Check if someone hasn't zapped us */
25 if ( fo == NULL || fo->fd == -1 )
30 if ( FILEOBJ_IS_EOF(fo) ) {
31 ghc_errtype = ERR_EOF;
36 /* Weird case: buffering has suddenly been turned off.
37 Return non-std value and deal with this case on the Haskell side.
39 if ( FILEOBJ_UNBUFFERED(fo) ) {
43 /* if input stream is connect to an output stream, flush this one first. */
44 if ( fo->connectedTo != NULL &&
45 fo->connectedTo->fd != -1 &&
46 (fo->connectedTo->flags & FILEOBJ_WRITE)
48 rc = flushFile((StgForeignPtr)fo->connectedTo);
50 if (rc < 0) return (rc == FILEOBJ_BLOCKED_WRITE ? FILEOBJ_BLOCKED_CONN_WRITE : rc);
52 /* RW object: flush the (output) buffer first. */
53 if ( FILEOBJ_WRITEABLE(fo) && FILEOBJ_JUST_WRITTEN(fo) && FILEOBJ_NEEDS_FLUSHING(fo) ) {
54 rc = flushBuffer(ptr);
55 if (rc < 0) return rc;
57 fo->flags = (fo->flags & ~FILEOBJ_RW_WRITE) | FILEOBJ_RW_READ;
59 /* return the unread parts of the file buffer..*/
60 if ( fo->flags & FILEOBJ_READ &&
62 fo->bufWPtr > fo->bufRPtr ) {
63 count = fo->bufWPtr - fo->bufRPtr;
69 fprintf(stderr, "rb: %d %d %d\n", fo->bufRPtr, fo->bufWPtr, fo->bufSize);
72 if ( fo->flags & FILEOBJ_NONBLOCKING_IO && inputReady (ptr,0) != 1 )
73 return FILEOBJ_BLOCKED_READ;
75 while ((count = read(fd, fo->buf, fo->bufSize)) <= 0) {
78 ghc_errtype = ERR_EOF;
81 } else if ( count == -1 && errno == EAGAIN) {
83 return FILEOBJ_BLOCKED_READ;
84 } else if ( count == -1 && errno != EINTR) {
95 /* Filling up a (block-buffered) buffer of length len */
97 readChunk(ptr,buf,len)
102 IOFileObject* fo = (IOFileObject*)ptr;
103 int count=0,rc=0, total_count;
107 /* Check if someone hasn't zapped us */
113 if ( fd == -1 ) /* File has been closed for us */
116 if ( FILEOBJ_IS_EOF(fo) ) {
117 ghc_errtype = ERR_EOF;
122 /* if input stream is connect to an output stream, flush it first */
123 if ( fo->connectedTo != NULL &&
124 fo->connectedTo->fd != -1 &&
125 (fo->connectedTo->flags & FILEOBJ_WRITE)
127 rc = flushFile((StgForeignPtr)fo->connectedTo);
129 if (rc < 0) return (rc == FILEOBJ_BLOCKED_WRITE ? FILEOBJ_BLOCKED_CONN_WRITE : rc);
131 /* RW object: flush the (output) buffer first. */
132 if ( FILEOBJ_WRITEABLE(fo) && FILEOBJ_JUST_WRITTEN(fo) && FILEOBJ_NEEDS_FLUSHING(fo) ) {
133 rc = flushBuffer(ptr);
134 if (rc < 0) return rc;
136 fo->flags = (fo->flags & ~FILEOBJ_RW_WRITE) | FILEOBJ_RW_READ;
138 /* copy the unread parts of the file buffer..*/
139 if ( FILEOBJ_READABLE(fo) &&
141 fo->bufWPtr >= fo->bufRPtr ) {
142 count = ( len < (fo->bufWPtr - fo->bufRPtr)) ? len : (fo->bufWPtr - fo->bufRPtr);
143 memcpy(buf,fo->buf, count);
149 if (len - count <= 0)
157 if ( fo->flags & FILEOBJ_NONBLOCKING_IO && inputReady (ptr,0) != 1 )
158 return FILEOBJ_BLOCKED_READ;
160 while ((count = read(fd, p, len)) < len) {
161 if ( count == 0 ) { /* EOF */
163 } else if ( count == -1 && errno == EAGAIN) {
165 return FILEOBJ_BLOCKED_READ;
166 } else if ( count == -1 && errno != EINTR) {
171 total_count += count;
176 total_count += count;
177 fo->bufWPtr = total_count;
183 readLine() tries to fill the buffer up with a line of chars, returning
184 the length of the resulting line.
186 Users of readLine() should immediately afterwards copy out the line
195 IOFileObject* fo = (IOFileObject*)ptr;
199 /* Check if someone hasn't zapped us */
200 if ( fo == NULL || fo->fd == -1 )
203 if ( FILEOBJ_IS_EOF(fo) ) {
204 ghc_errtype = ERR_EOF;
209 /* Weird case: buffering has been turned off.
210 Return non-std value and deal with this case on the Haskell side.
212 if ( FILEOBJ_UNBUFFERED(fo) ) {
216 /* if input stream is connect to an output stream, flush it first */
217 if ( fo->connectedTo != NULL &&
218 fo->connectedTo->fd != -1 &&
219 (fo->connectedTo->flags & FILEOBJ_WRITE)
221 rc = flushFile((StgForeignPtr)fo->connectedTo);
223 if (rc < 0) return (rc == FILEOBJ_BLOCKED_WRITE ? FILEOBJ_BLOCKED_CONN_WRITE : rc);
225 /* RW object: flush the (output) buffer first. */
226 if ( FILEOBJ_WRITEABLE(fo) && FILEOBJ_JUST_WRITTEN(fo) ) {
227 rc = flushBuffer(ptr);
228 if (rc < 0) return rc;
230 fo->flags = (fo->flags & ~FILEOBJ_RW_WRITE) | FILEOBJ_RW_READ;
232 if ( fo->bufRPtr < 0 || fo->bufRPtr >= fo->bufWPtr ) { /* Buffer is empty */
233 fo->bufRPtr=0; fo->bufWPtr=0;
234 rc = fill_up_line_buffer(fo);
235 if (rc < 0) return rc;
239 unsigned char* s1 = memchr((unsigned char *)fo->buf+fo->bufRPtr, '\n', fo->bufWPtr - fo->bufRPtr);
240 if (s1 != NULL ) { /* Found one */
241 /* Note: we *don't* zero terminate the line */
242 count = s1 - ((unsigned char*)fo->buf + fo->bufRPtr) + 1;
243 fo->bufRPtr += count;
246 /* Just return partial line */
247 count = fo->bufWPtr - fo->bufRPtr;
248 fo->bufRPtr += count;
259 IOFileObject* fo= (IOFileObject*)ptr;
263 /* Check if someone hasn't zapped us */
264 if ( fo == NULL || fo->fd == -1)
267 if ( FILEOBJ_IS_EOF(fo) ) {
268 ghc_errtype = ERR_EOF;
273 /* Buffering has been changed, report back */
274 if ( FILEOBJ_LINEBUFFERED(fo) ) {
276 } else if ( FILEOBJ_BLOCKBUFFERED(fo) ) {
280 /* if input stream is connect to an output stream, flush it first */
281 if ( fo->connectedTo != NULL &&
282 fo->connectedTo->fd != -1 &&
283 (fo->connectedTo->flags & FILEOBJ_WRITE)
285 rc = flushFile((StgForeignPtr)fo->connectedTo);
287 if (rc < 0) return (rc == FILEOBJ_BLOCKED_WRITE ? FILEOBJ_BLOCKED_CONN_WRITE : rc);
289 /* RW object: flush the (output) buffer first. */
290 if ( FILEOBJ_WRITEABLE(fo) && FILEOBJ_JUST_WRITTEN(fo) && FILEOBJ_NEEDS_FLUSHING(fo) ) {
291 rc = flushBuffer(ptr);
292 if (rc < 0) return rc;
294 fo->flags = (fo->flags & ~FILEOBJ_RW_WRITE) | FILEOBJ_RW_READ;
296 if ( fo->flags & FILEOBJ_NONBLOCKING_IO && inputReady (ptr,0) != 1 )
297 return FILEOBJ_BLOCKED_READ;
299 while ( (count = read(fo->fd, &c, 1)) <= 0 ) {
301 ghc_errtype = ERR_EOF;
304 } else if ( count == -1 && errno == EAGAIN) {
306 return FILEOBJ_BLOCKED_READ;
307 } else if ( count == -1 && errno != EINTR) {
314 if ( isatty(fo->fd) && c == EOT ) {