2 * (c) The GRASP/AQUA Project, Glasgow University, 1994-1998
4 * $Id: readFile.c,v 1.14 2000/04/04 11:01:33 simonmar 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. */
25 readBlock(StgForeignPtr ptr)
27 IOFileObject* fo = (IOFileObject*)ptr;
31 /* Check if someone hasn't zapped us */
32 if ( fo == NULL || fo->fd == -1 )
37 if ( FILEOBJ_IS_EOF(fo) ) {
38 ghc_errtype = ERR_EOF;
43 /* Weird case: buffering has suddenly been turned off.
44 Return non-std value and deal with this case on the Haskell side.
46 if ( FILEOBJ_UNBUFFERED(fo) ) {
50 /* if input stream is connect to an output stream, flush this one first. */
51 if ( fo->connectedTo != NULL &&
52 fo->connectedTo->fd != -1 &&
53 (fo->connectedTo->flags & FILEOBJ_WRITE)
55 rc = flushFile((StgForeignPtr)fo->connectedTo);
57 if (rc < 0) return (rc == FILEOBJ_BLOCKED_WRITE ? FILEOBJ_BLOCKED_CONN_WRITE : rc);
59 /* RW object: flush the (output) buffer first. */
60 if ( FILEOBJ_WRITEABLE(fo) && FILEOBJ_JUST_WRITTEN(fo) && FILEOBJ_NEEDS_FLUSHING(fo) ) {
61 rc = flushBuffer(ptr);
62 if (rc < 0) return rc;
64 fo->flags = (fo->flags & ~FILEOBJ_RW_WRITE) | FILEOBJ_RW_READ;
66 /* return the unread parts of the file buffer..*/
67 if ( fo->flags & FILEOBJ_READ &&
69 fo->bufWPtr > fo->bufRPtr ) {
70 count = fo->bufWPtr - fo->bufRPtr;
76 fprintf(stderr, "rb: %d %d %d\n", fo->bufRPtr, fo->bufWPtr, fo->bufSize);
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(FileObjet *, void *, int)
113 * FILEOBJ_BLOCKED_CONN_WRITE blocking while flushing
114 * buffer of connected handle.
115 * FILEOBJ_BLOCKED_READ didn't read anything; would block
116 * n, where n > 0 read n bytes into buffer.
120 readChunk(StgForeignPtr ptr, StgAddr buf, StgInt off, StgInt len)
122 IOFileObject* fo = (IOFileObject*)ptr;
123 int count, rc=0, total_count=0;
127 /* Check if someone hasn't zapped us */
133 if ( fd == -1 ) /* File has been closed for us */
136 if ( FILEOBJ_IS_EOF(fo) ) {
137 ghc_errtype = ERR_EOF;
142 /* if input stream is connect to an output stream, flush it first */
143 if ( fo->connectedTo != NULL &&
144 fo->connectedTo->fd != -1 &&
145 (fo->connectedTo->flags & FILEOBJ_WRITE)
147 rc = flushFile((StgForeignPtr)fo->connectedTo);
149 if (rc < 0) return (rc == FILEOBJ_BLOCKED_WRITE ? FILEOBJ_BLOCKED_CONN_WRITE : rc);
151 /* RW object: flush the (output) buffer first. */
152 if ( FILEOBJ_WRITEABLE(fo) && FILEOBJ_JUST_WRITTEN(fo) && FILEOBJ_NEEDS_FLUSHING(fo) ) {
153 rc = flushBuffer(ptr);
154 if (rc < 0) return rc;
156 fo->flags = (fo->flags & ~FILEOBJ_RW_WRITE) | FILEOBJ_RW_READ;
160 /* copy the unread parts of the file buffer..*/
161 if ( FILEOBJ_READABLE(fo) &&
163 fo->bufWPtr >= fo->bufRPtr ) {
165 if (fo->bufWPtr - fo->bufRPtr >= len) {
166 /* buffer has enough data to fulfill the request */
167 memcpy(buf, fo->buf + fo->bufRPtr, len);
171 /* can only partially fulfill the request from the buffer */
172 count = fo->bufWPtr - fo->bufRPtr;
173 memcpy(buf, fo->buf + fo->bufRPtr, count);
185 fo->flags & FILEOBJ_WINSOCK ?
186 recv(fd, p, len, 0) :
187 read(fd, p, len))) <= 0 ) {
189 read(fd, p, len))) <= 0 ) {
194 if ( total_count == 0 ) {
195 ghc_errtype = ERR_EOF;
203 } else if ( count == -1 && errno == EAGAIN) {
206 return total_count; /* partial read */
208 return FILEOBJ_BLOCKED_READ;
211 } else if ( count == -1 && errno != EINTR) {
218 total_count += count;
223 readLine() tries to fill the buffer up with a line of chars, returning
224 the length of the resulting line.
226 Users of readLine() should immediately afterwards copy out the line
232 readLine(StgForeignPtr ptr)
234 IOFileObject* fo = (IOFileObject*)ptr;
237 /* Check if someone hasn't zapped us */
238 if ( fo == NULL || fo->fd == -1 )
241 if ( FILEOBJ_IS_EOF(fo) ) {
242 ghc_errtype = ERR_EOF;
247 /* Weird case: buffering has been turned off.
248 Return non-std value and deal with this case on the Haskell side.
250 if ( FILEOBJ_UNBUFFERED(fo) ) {
254 /* if input stream is connect to an output stream, flush it first */
255 if ( fo->connectedTo != NULL &&
256 fo->connectedTo->fd != -1 &&
257 (fo->connectedTo->flags & FILEOBJ_WRITE)
259 rc = flushFile((StgForeignPtr)fo->connectedTo);
261 if (rc < 0) return (rc == FILEOBJ_BLOCKED_WRITE ? FILEOBJ_BLOCKED_CONN_WRITE : rc);
263 /* RW object: flush the (output) buffer first. */
264 if ( FILEOBJ_WRITEABLE(fo) && FILEOBJ_JUST_WRITTEN(fo) ) {
265 rc = flushBuffer(ptr);
266 if (rc < 0) return rc;
268 fo->flags = (fo->flags & ~FILEOBJ_RW_WRITE) | FILEOBJ_RW_READ;
270 if ( fo->bufRPtr < 0 || fo->bufRPtr >= fo->bufWPtr ) { /* Buffer is empty */
271 fo->bufRPtr=0; fo->bufWPtr=0;
272 rc = fill_up_line_buffer(fo);
273 if (rc < 0) return rc;
277 unsigned char* s1 = memchr((unsigned char *)fo->buf+fo->bufRPtr, '\n', fo->bufWPtr - fo->bufRPtr);
278 if (s1 != NULL ) { /* Found one */
279 /* Note: we *don't* zero terminate the line */
280 count = s1 - ((unsigned char*)fo->buf + fo->bufRPtr) + 1;
281 fo->bufRPtr += count;
284 /* Just return partial line */
285 count = fo->bufWPtr - fo->bufRPtr;
286 fo->bufRPtr += count;
294 readChar(StgForeignPtr ptr)
296 IOFileObject* fo= (IOFileObject*)ptr;
300 /* Check if someone hasn't zapped us */
301 if ( fo == NULL || fo->fd == -1)
304 if ( FILEOBJ_IS_EOF(fo) ) {
305 ghc_errtype = ERR_EOF;
310 /* Buffering has been changed, report back */
311 if ( FILEOBJ_LINEBUFFERED(fo) ) {
313 } else if ( FILEOBJ_BLOCKBUFFERED(fo) ) {
317 /* if input stream is connect to an output stream, flush it first */
318 if ( fo->connectedTo != NULL &&
319 fo->connectedTo->fd != -1 &&
320 (fo->connectedTo->flags & FILEOBJ_WRITE)
322 rc = flushFile((StgForeignPtr)fo->connectedTo);
324 if (rc < 0) return (rc == FILEOBJ_BLOCKED_WRITE ? FILEOBJ_BLOCKED_CONN_WRITE : rc);
326 /* RW object: flush the (output) buffer first. */
327 if ( FILEOBJ_WRITEABLE(fo) && FILEOBJ_JUST_WRITTEN(fo) && FILEOBJ_NEEDS_FLUSHING(fo) ) {
328 rc = flushBuffer(ptr);
329 if (rc < 0) return rc;
331 fo->flags = (fo->flags & ~FILEOBJ_RW_WRITE) | FILEOBJ_RW_READ;
336 fo->flags & FILEOBJ_WINSOCK ?
337 recv(fo->fd, &c, 1, 0) :
338 read(fo->fd, &c, 1))) <= 0 ) {
340 read(fo->fd, &c, 1))) <= 0 ) {
343 ghc_errtype = ERR_EOF;
346 } else if ( count == -1 && errno == EAGAIN) {
348 return FILEOBJ_BLOCKED_READ;
349 } else if ( count == -1 && errno != EINTR) {
356 if ( isatty(fo->fd) && c == EOT ) {