2 * (c) The GRASP/AQUA Project, Glasgow University, 1994-1998
4 * $Id: readFile.c,v 1.7 1999/07/12 10:43:13 sof Exp $
6 * hGetContents Runtime Support
12 #if defined(HAVE_WINSOCK_H) && !defined(__CYGWIN__) && !defined(__CYGWIN32__)
22 /* Filling up a (block-buffered) buffer, that
23 is completely empty. */
28 IOFileObject* fo = (IOFileObject*)ptr;
32 /* Check if someone hasn't zapped us */
33 if ( fo == NULL || fo->fd == -1 )
38 if ( FILEOBJ_IS_EOF(fo) ) {
39 ghc_errtype = ERR_EOF;
44 /* Weird case: buffering has suddenly been turned off.
45 Return non-std value and deal with this case on the Haskell side.
47 if ( FILEOBJ_UNBUFFERED(fo) ) {
51 /* if input stream is connect to an output stream, flush this one first. */
52 if ( fo->connectedTo != NULL &&
53 fo->connectedTo->fd != -1 &&
54 (fo->connectedTo->flags & FILEOBJ_WRITE)
56 rc = flushFile((StgForeignPtr)fo->connectedTo);
58 if (rc < 0) return (rc == FILEOBJ_BLOCKED_WRITE ? FILEOBJ_BLOCKED_CONN_WRITE : rc);
60 /* RW object: flush the (output) buffer first. */
61 if ( FILEOBJ_WRITEABLE(fo) && FILEOBJ_JUST_WRITTEN(fo) && FILEOBJ_NEEDS_FLUSHING(fo) ) {
62 rc = flushBuffer(ptr);
63 if (rc < 0) return rc;
65 fo->flags = (fo->flags & ~FILEOBJ_RW_WRITE) | FILEOBJ_RW_READ;
67 /* return the unread parts of the file buffer..*/
68 if ( fo->flags & FILEOBJ_READ &&
70 fo->bufWPtr > fo->bufRPtr ) {
71 count = fo->bufWPtr - fo->bufRPtr;
77 fprintf(stderr, "rb: %d %d %d\n", fo->bufRPtr, fo->bufWPtr, fo->bufSize);
80 if ( fo->flags & FILEOBJ_NONBLOCKING_IO && inputReady (ptr,0) != 1 )
81 return FILEOBJ_BLOCKED_READ;
86 fo->flags & FILEOBJ_WINSOCK ?
87 recv(fd, fo->buf, fo->bufSize, 0) :
88 read(fd, fo->buf, fo->bufSize))) <= 0 ) {
90 read(fd, fo->buf, fo->bufSize))) <= 0 ) {
94 ghc_errtype = ERR_EOF;
97 } else if ( count == -1 && errno == EAGAIN) {
99 return FILEOBJ_BLOCKED_READ;
100 } else if ( count == -1 && errno != EINTR) {
111 /* Filling up a (block-buffered) buffer of length len */
113 readChunk(ptr,buf,len)
118 IOFileObject* fo = (IOFileObject*)ptr;
119 int count=0,rc=0, total_count;
123 /* Check if someone hasn't zapped us */
129 if ( fd == -1 ) /* File has been closed for us */
132 if ( FILEOBJ_IS_EOF(fo) ) {
133 ghc_errtype = ERR_EOF;
138 /* if input stream is connect to an output stream, flush it first */
139 if ( fo->connectedTo != NULL &&
140 fo->connectedTo->fd != -1 &&
141 (fo->connectedTo->flags & FILEOBJ_WRITE)
143 rc = flushFile((StgForeignPtr)fo->connectedTo);
145 if (rc < 0) return (rc == FILEOBJ_BLOCKED_WRITE ? FILEOBJ_BLOCKED_CONN_WRITE : rc);
147 /* RW object: flush the (output) buffer first. */
148 if ( FILEOBJ_WRITEABLE(fo) && FILEOBJ_JUST_WRITTEN(fo) && FILEOBJ_NEEDS_FLUSHING(fo) ) {
149 rc = flushBuffer(ptr);
150 if (rc < 0) return rc;
152 fo->flags = (fo->flags & ~FILEOBJ_RW_WRITE) | FILEOBJ_RW_READ;
154 /* copy the unread parts of the file buffer..*/
155 if ( FILEOBJ_READABLE(fo) &&
157 fo->bufWPtr >= fo->bufRPtr ) {
158 count = ( len < (fo->bufWPtr - fo->bufRPtr)) ? len : (fo->bufWPtr - fo->bufRPtr);
159 memcpy(buf,fo->buf, count);
165 if (len - count <= 0)
173 if ( fo->flags & FILEOBJ_NONBLOCKING_IO && inputReady (ptr,0) != 1 )
174 return FILEOBJ_BLOCKED_READ;
179 fo->flags & FILEOBJ_WINSOCK ?
180 recv(fd, p, len, 0) :
181 read(fd, p, len))) <= 0 ) {
183 read(fd, p, len))) <= 0 ) {
185 if ( count == 0 ) { /* EOF */
187 } else if ( count == -1 && errno == EAGAIN) {
189 return FILEOBJ_BLOCKED_READ;
190 } else if ( count == -1 && errno != EINTR) {
195 total_count += count;
200 total_count += count;
201 fo->bufWPtr = total_count;
207 readLine() tries to fill the buffer up with a line of chars, returning
208 the length of the resulting line.
210 Users of readLine() should immediately afterwards copy out the line
219 IOFileObject* fo = (IOFileObject*)ptr;
223 /* Check if someone hasn't zapped us */
224 if ( fo == NULL || fo->fd == -1 )
227 if ( FILEOBJ_IS_EOF(fo) ) {
228 ghc_errtype = ERR_EOF;
233 /* Weird case: buffering has been turned off.
234 Return non-std value and deal with this case on the Haskell side.
236 if ( FILEOBJ_UNBUFFERED(fo) ) {
240 /* if input stream is connect to an output stream, flush it first */
241 if ( fo->connectedTo != NULL &&
242 fo->connectedTo->fd != -1 &&
243 (fo->connectedTo->flags & FILEOBJ_WRITE)
245 rc = flushFile((StgForeignPtr)fo->connectedTo);
247 if (rc < 0) return (rc == FILEOBJ_BLOCKED_WRITE ? FILEOBJ_BLOCKED_CONN_WRITE : rc);
249 /* RW object: flush the (output) buffer first. */
250 if ( FILEOBJ_WRITEABLE(fo) && FILEOBJ_JUST_WRITTEN(fo) ) {
251 rc = flushBuffer(ptr);
252 if (rc < 0) return rc;
254 fo->flags = (fo->flags & ~FILEOBJ_RW_WRITE) | FILEOBJ_RW_READ;
256 if ( fo->bufRPtr < 0 || fo->bufRPtr >= fo->bufWPtr ) { /* Buffer is empty */
257 fo->bufRPtr=0; fo->bufWPtr=0;
258 rc = fill_up_line_buffer(fo);
259 if (rc < 0) return rc;
263 unsigned char* s1 = memchr((unsigned char *)fo->buf+fo->bufRPtr, '\n', fo->bufWPtr - fo->bufRPtr);
264 if (s1 != NULL ) { /* Found one */
265 /* Note: we *don't* zero terminate the line */
266 count = s1 - ((unsigned char*)fo->buf + fo->bufRPtr) + 1;
267 fo->bufRPtr += count;
270 /* Just return partial line */
271 count = fo->bufWPtr - fo->bufRPtr;
272 fo->bufRPtr += count;
283 IOFileObject* fo= (IOFileObject*)ptr;
287 /* Check if someone hasn't zapped us */
288 if ( fo == NULL || fo->fd == -1)
291 if ( FILEOBJ_IS_EOF(fo) ) {
292 ghc_errtype = ERR_EOF;
297 /* Buffering has been changed, report back */
298 if ( FILEOBJ_LINEBUFFERED(fo) ) {
300 } else if ( FILEOBJ_BLOCKBUFFERED(fo) ) {
304 /* if input stream is connect to an output stream, flush it first */
305 if ( fo->connectedTo != NULL &&
306 fo->connectedTo->fd != -1 &&
307 (fo->connectedTo->flags & FILEOBJ_WRITE)
309 rc = flushFile((StgForeignPtr)fo->connectedTo);
311 if (rc < 0) return (rc == FILEOBJ_BLOCKED_WRITE ? FILEOBJ_BLOCKED_CONN_WRITE : rc);
313 /* RW object: flush the (output) buffer first. */
314 if ( FILEOBJ_WRITEABLE(fo) && FILEOBJ_JUST_WRITTEN(fo) && FILEOBJ_NEEDS_FLUSHING(fo) ) {
315 rc = flushBuffer(ptr);
316 if (rc < 0) return rc;
318 fo->flags = (fo->flags & ~FILEOBJ_RW_WRITE) | FILEOBJ_RW_READ;
320 if ( fo->flags & FILEOBJ_NONBLOCKING_IO && inputReady (ptr,0) != 1 )
321 return FILEOBJ_BLOCKED_READ;
326 fo->flags & FILEOBJ_WINSOCK ?
327 recv(fo->fd, &c, 1, 0) :
328 read(fo->fd, &c, 1))) <= 0 ) {
330 read(fo->fd, &c, 1))) <= 0 ) {
333 ghc_errtype = ERR_EOF;
336 } else if ( count == -1 && errno == EAGAIN) {
338 return FILEOBJ_BLOCKED_READ;
339 } else if ( count == -1 && errno != EINTR) {
346 if ( isatty(fo->fd) && c == EOT ) {