2 * (c) The GRASP/AQUA Project, Glasgow University, 1994-1998
4 * $Id: readFile.c,v 1.5 1999/07/01 13:12:09 simonmar Exp $
6 * hGetContents Runtime Support
18 /* Filling up a (block-buffered) buffer, that
19 is completely empty. */
24 IOFileObject* fo = (IOFileObject*)ptr;
28 /* Check if someone hasn't zapped us */
29 if ( fo == NULL || fo->fd == -1 )
34 if ( FILEOBJ_IS_EOF(fo) ) {
35 ghc_errtype = ERR_EOF;
40 /* Weird case: buffering has suddenly been turned off.
41 Return non-std value and deal with this case on the Haskell side.
43 if ( FILEOBJ_UNBUFFERED(fo) ) {
47 /* if input stream is connect to an output stream, flush this one first. */
48 if ( fo->connectedTo != NULL &&
49 fo->connectedTo->fd != -1 &&
50 (fo->connectedTo->flags & FILEOBJ_WRITE)
52 rc = flushFile((StgForeignPtr)fo->connectedTo);
54 if (rc < 0) return (rc == FILEOBJ_BLOCKED_WRITE ? FILEOBJ_BLOCKED_CONN_WRITE : rc);
56 /* RW object: flush the (output) buffer first. */
57 if ( FILEOBJ_WRITEABLE(fo) && FILEOBJ_JUST_WRITTEN(fo) && FILEOBJ_NEEDS_FLUSHING(fo) ) {
58 rc = flushBuffer(ptr);
59 if (rc < 0) return rc;
61 fo->flags = (fo->flags & ~FILEOBJ_RW_WRITE) | FILEOBJ_RW_READ;
63 /* return the unread parts of the file buffer..*/
64 if ( fo->flags & FILEOBJ_READ &&
66 fo->bufWPtr > fo->bufRPtr ) {
67 count = fo->bufWPtr - fo->bufRPtr;
73 fprintf(stderr, "rb: %d %d %d\n", fo->bufRPtr, fo->bufWPtr, fo->bufSize);
76 if ( fo->flags & FILEOBJ_NONBLOCKING_IO && inputReady (ptr,0) != 1 )
77 return FILEOBJ_BLOCKED_READ;
82 fo->flags & FILEOBJ_WINSOCK ?
83 recv(fd, fo->buf, fo->bufSize, 0) :
84 read(fd, fo->buf, fo->bufSize))) <= 0 ) {
86 read(fd, fo->buf, fo->bufSize))) <= 0 ) {
90 ghc_errtype = ERR_EOF;
93 } else if ( count == -1 && errno == EAGAIN) {
95 return FILEOBJ_BLOCKED_READ;
96 } else if ( count == -1 && errno != EINTR) {
107 /* Filling up a (block-buffered) buffer of length len */
109 readChunk(ptr,buf,len)
114 IOFileObject* fo = (IOFileObject*)ptr;
115 int count=0,rc=0, total_count;
119 /* Check if someone hasn't zapped us */
125 if ( fd == -1 ) /* File has been closed for us */
128 if ( FILEOBJ_IS_EOF(fo) ) {
129 ghc_errtype = ERR_EOF;
134 /* if input stream is connect to an output stream, flush it first */
135 if ( fo->connectedTo != NULL &&
136 fo->connectedTo->fd != -1 &&
137 (fo->connectedTo->flags & FILEOBJ_WRITE)
139 rc = flushFile((StgForeignPtr)fo->connectedTo);
141 if (rc < 0) return (rc == FILEOBJ_BLOCKED_WRITE ? FILEOBJ_BLOCKED_CONN_WRITE : rc);
143 /* RW object: flush the (output) buffer first. */
144 if ( FILEOBJ_WRITEABLE(fo) && FILEOBJ_JUST_WRITTEN(fo) && FILEOBJ_NEEDS_FLUSHING(fo) ) {
145 rc = flushBuffer(ptr);
146 if (rc < 0) return rc;
148 fo->flags = (fo->flags & ~FILEOBJ_RW_WRITE) | FILEOBJ_RW_READ;
150 /* copy the unread parts of the file buffer..*/
151 if ( FILEOBJ_READABLE(fo) &&
153 fo->bufWPtr >= fo->bufRPtr ) {
154 count = ( len < (fo->bufWPtr - fo->bufRPtr)) ? len : (fo->bufWPtr - fo->bufRPtr);
155 memcpy(buf,fo->buf, count);
161 if (len - count <= 0)
169 if ( fo->flags & FILEOBJ_NONBLOCKING_IO && inputReady (ptr,0) != 1 )
170 return FILEOBJ_BLOCKED_READ;
174 #ifdef HAVE_WINSOCK_H
175 fo->flags & FILEOBJ_WINSOCK ?
176 recv(fd, p, len, 0) :
177 read(fd, p, len))) <= 0 ) {
179 read(fd, p, len))) <= 0 ) {
181 if ( count == 0 ) { /* EOF */
183 } else if ( count == -1 && errno == EAGAIN) {
185 return FILEOBJ_BLOCKED_READ;
186 } else if ( count == -1 && errno != EINTR) {
191 total_count += count;
196 total_count += count;
197 fo->bufWPtr = total_count;
203 readLine() tries to fill the buffer up with a line of chars, returning
204 the length of the resulting line.
206 Users of readLine() should immediately afterwards copy out the line
215 IOFileObject* fo = (IOFileObject*)ptr;
219 /* Check if someone hasn't zapped us */
220 if ( fo == NULL || fo->fd == -1 )
223 if ( FILEOBJ_IS_EOF(fo) ) {
224 ghc_errtype = ERR_EOF;
229 /* Weird case: buffering has been turned off.
230 Return non-std value and deal with this case on the Haskell side.
232 if ( FILEOBJ_UNBUFFERED(fo) ) {
236 /* if input stream is connect to an output stream, flush it first */
237 if ( fo->connectedTo != NULL &&
238 fo->connectedTo->fd != -1 &&
239 (fo->connectedTo->flags & FILEOBJ_WRITE)
241 rc = flushFile((StgForeignPtr)fo->connectedTo);
243 if (rc < 0) return (rc == FILEOBJ_BLOCKED_WRITE ? FILEOBJ_BLOCKED_CONN_WRITE : rc);
245 /* RW object: flush the (output) buffer first. */
246 if ( FILEOBJ_WRITEABLE(fo) && FILEOBJ_JUST_WRITTEN(fo) ) {
247 rc = flushBuffer(ptr);
248 if (rc < 0) return rc;
250 fo->flags = (fo->flags & ~FILEOBJ_RW_WRITE) | FILEOBJ_RW_READ;
252 if ( fo->bufRPtr < 0 || fo->bufRPtr >= fo->bufWPtr ) { /* Buffer is empty */
253 fo->bufRPtr=0; fo->bufWPtr=0;
254 rc = fill_up_line_buffer(fo);
255 if (rc < 0) return rc;
259 unsigned char* s1 = memchr((unsigned char *)fo->buf+fo->bufRPtr, '\n', fo->bufWPtr - fo->bufRPtr);
260 if (s1 != NULL ) { /* Found one */
261 /* Note: we *don't* zero terminate the line */
262 count = s1 - ((unsigned char*)fo->buf + fo->bufRPtr) + 1;
263 fo->bufRPtr += count;
266 /* Just return partial line */
267 count = fo->bufWPtr - fo->bufRPtr;
268 fo->bufRPtr += count;
279 IOFileObject* fo= (IOFileObject*)ptr;
283 /* Check if someone hasn't zapped us */
284 if ( fo == NULL || fo->fd == -1)
287 if ( FILEOBJ_IS_EOF(fo) ) {
288 ghc_errtype = ERR_EOF;
293 /* Buffering has been changed, report back */
294 if ( FILEOBJ_LINEBUFFERED(fo) ) {
296 } else if ( FILEOBJ_BLOCKBUFFERED(fo) ) {
300 /* if input stream is connect to an output stream, flush it first */
301 if ( fo->connectedTo != NULL &&
302 fo->connectedTo->fd != -1 &&
303 (fo->connectedTo->flags & FILEOBJ_WRITE)
305 rc = flushFile((StgForeignPtr)fo->connectedTo);
307 if (rc < 0) return (rc == FILEOBJ_BLOCKED_WRITE ? FILEOBJ_BLOCKED_CONN_WRITE : rc);
309 /* RW object: flush the (output) buffer first. */
310 if ( FILEOBJ_WRITEABLE(fo) && FILEOBJ_JUST_WRITTEN(fo) && FILEOBJ_NEEDS_FLUSHING(fo) ) {
311 rc = flushBuffer(ptr);
312 if (rc < 0) return rc;
314 fo->flags = (fo->flags & ~FILEOBJ_RW_WRITE) | FILEOBJ_RW_READ;
316 if ( fo->flags & FILEOBJ_NONBLOCKING_IO && inputReady (ptr,0) != 1 )
317 return FILEOBJ_BLOCKED_READ;
321 #ifdef HAVE_WINSOCK_H
322 fo->flags & FILEOBJ_WINSOCK ?
323 recv(fo->fd, &c, 1, 0) :
324 read(fo->fd, &c, 1))) <= 0 ) {
326 read(fo->fd, &c, 1))) <= 0 ) {
329 ghc_errtype = ERR_EOF;
332 } else if ( count == -1 && errno == EAGAIN) {
334 return FILEOBJ_BLOCKED_READ;
335 } else if ( count == -1 && errno != EINTR) {
342 if ( isatty(fo->fd) && c == EOT ) {