diff options
author | simonmar <unknown> | 2000-03-10 15:23:40 +0000 |
---|---|---|
committer | simonmar <unknown> | 2000-03-10 15:23:40 +0000 |
commit | f9a0273cd8017d27e81e314f067b0d5197918d68 (patch) | |
tree | 21f0cd2c610f5786d6eae52b3366f30ade5a9083 /ghc/lib/std/cbits/readFile.c | |
parent | 2f4676b44b3800815c5d08a8518562e20046d082 (diff) | |
download | haskell-f9a0273cd8017d27e81e314f067b0d5197918d68.tar.gz |
[project @ 2000-03-10 15:23:40 by simonmar]
Fix h{Fill,Put}Buf(BA)?. They now work in the presence of
partial/blocking reads and writes, and hPutBuf now doesn't hold on to
the handle while it's blocking.
Diffstat (limited to 'ghc/lib/std/cbits/readFile.c')
-rw-r--r-- | ghc/lib/std/cbits/readFile.c | 43 |
1 files changed, 27 insertions, 16 deletions
diff --git a/ghc/lib/std/cbits/readFile.c b/ghc/lib/std/cbits/readFile.c index 432a7385c6..a68f3aaf81 100644 --- a/ghc/lib/std/cbits/readFile.c +++ b/ghc/lib/std/cbits/readFile.c @@ -1,7 +1,7 @@ /* * (c) The GRASP/AQUA Project, Glasgow University, 1994-1998 * - * $Id: readFile.c,v 1.10 2000/01/18 12:42:12 simonmar Exp $ + * $Id: readFile.c,v 1.11 2000/03/10 15:23:40 simonmar Exp $ * * hGetContents Runtime Support */ @@ -105,8 +105,19 @@ readBlock(StgForeignPtr ptr) } /* Filling up a (block-buffered) buffer of length len */ + +/* readChunk(FileObjet *, void *, int) + * returns: + * -1 error + * -2 object closed + * FILEOBJ_BLOCKED_CONN_WRITE blocking while flushing + * buffer of connected handle. + * FILEOBJ_BLOCKED_READ didn't read anything; would block + * n, where n > 0 read n bytes into buffer. + */ + StgInt -readChunk(StgForeignPtr ptr, StgAddr buf, StgInt len) +readChunk(StgForeignPtr ptr, StgAddr buf, StgInt off, StgInt len) { IOFileObject* fo = (IOFileObject*)ptr; int count=0,rc=0, total_count; @@ -159,7 +170,7 @@ readChunk(StgForeignPtr ptr, StgAddr buf, StgInt len) return count; len -= count; - p = buf; + p = buf+off; p += count; total_count = count; @@ -172,28 +183,28 @@ readChunk(StgForeignPtr ptr, StgAddr buf, StgInt len) #else read(fd, p, len))) <= 0 ) { #endif - if ( count == 0 ) { /* EOF */ - break; + /* EOF */ + if ( count == 0 ) { + FILEOBJ_SET_EOF(fo); + return total_count; + + /* Blocking */ } else if ( count == -1 && errno == EAGAIN) { - /* ToDo: partial/blocked reads?????? Looks like we don't recover - * from this properly. - */ errno = 0; - return FILEOBJ_BLOCKED_READ; + if (total_count > 0) + return total_count; /* partial read */ + else + return FILEOBJ_BLOCKED_READ; + + /* Error */ } else if ( count == -1 && errno != EINTR) { cvtErrno(); stdErrno(); return -1; - } - total_count += count; - len -= count; - p += count; + } } total_count += count; - /* ToDo: might point beyond the end of the buffer??? */ - fo->bufWPtr = total_count; - fo->bufRPtr = 0; return total_count; } |