[project @ 2000-03-17 09:48:48 by simonmar]
[ghc-hetmet.git] / ghc / lib / std / cbits / readFile.c
index 8949ba2..a68f3aa 100644 (file)
@@ -1,7 +1,7 @@
 /* 
  * (c) The GRASP/AQUA Project, Glasgow University, 1994-1998
  *
- * $Id: readFile.c,v 1.4 1999/05/05 10:33:16 sof Exp $
+ * $Id: readFile.c,v 1.11 2000/03/10 15:23:40 simonmar Exp $
  *
  * hGetContents Runtime Support
  */
@@ -9,7 +9,11 @@
 #include "Rts.h"
 #include "stgio.h"
 
-#ifdef HAVE_WINSOCK_H
+#if defined(HAVE_WINSOCK_H) && !defined(__CYGWIN__) && !defined(__CYGWIN32__)
+#define USE_WINSOCK
+#endif
+
+#ifdef USE_WINSOCK
 #include <winsock.h>
 #endif
 
@@ -18,8 +22,7 @@
 /* Filling up a (block-buffered) buffer, that
    is completely empty. */
 StgInt
-readBlock(ptr)
-StgForeignPtr ptr;
+readBlock(StgForeignPtr ptr)
 {
     IOFileObject* fo = (IOFileObject*)ptr;
     int count,rc=0;
@@ -73,12 +76,9 @@ StgForeignPtr ptr;
     fprintf(stderr, "rb: %d %d %d\n", fo->bufRPtr, fo->bufWPtr, fo->bufSize);
 #endif
 
-    if ( fo->flags & FILEOBJ_NONBLOCKING_IO && inputReady (ptr,0) != 1 )
-      return FILEOBJ_BLOCKED_READ;
-
     while ((count =
             (
-#ifdef HAVE_WINSOCK_H
+#ifdef USE_WINSOCK
               fo->flags & FILEOBJ_WINSOCK ?
                 recv(fd, fo->buf, fo->bufSize, 0) :
                 read(fd, fo->buf, fo->bufSize))) <= 0 ) {
@@ -105,11 +105,19 @@ 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(ptr,buf,len)
-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;
@@ -162,40 +170,41 @@ StgInt len;
        return count;
 
     len -= count;
-    p = buf;
+    p = buf+off;
     p += count;
     total_count = count;
 
-    if ( fo->flags & FILEOBJ_NONBLOCKING_IO && inputReady (ptr,0) != 1 )
-      return FILEOBJ_BLOCKED_READ;
-
     while ((count =
              (
-#ifdef HAVE_WINSOCK_H
+#ifdef USE_WINSOCK
               fo->flags & FILEOBJ_WINSOCK ?
                 recv(fd, p, len, 0) :
                 read(fd, p, len))) <= 0 ) {
 #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) {
            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;
-    fo->bufWPtr = total_count;
-    fo->bufRPtr = 0;
     return total_count;
 }
 
@@ -209,11 +218,9 @@ StgInt len;
 */
 
 StgInt
-readLine(ptr)
-StgForeignPtr ptr;
+readLine(StgForeignPtr ptr)
 {
     IOFileObject* fo = (IOFileObject*)ptr;
-    char *s;
     int rc=0, count;
 
     /* Check if someone hasn't zapped us */
@@ -273,12 +280,11 @@ StgForeignPtr ptr;
 }
 
 StgInt
-readChar(ptr)
-StgForeignPtr ptr;
+readChar(StgForeignPtr ptr)
 {
     IOFileObject* fo= (IOFileObject*)ptr;
     int count,rc=0;
-    char c;
+    unsigned char c;
 
     /* Check if someone hasn't zapped us */
     if ( fo == NULL || fo->fd == -1)
@@ -313,12 +319,9 @@ StgForeignPtr ptr;
     }
     fo->flags = (fo->flags & ~FILEOBJ_RW_WRITE) | FILEOBJ_RW_READ;
 
-    if ( fo->flags & FILEOBJ_NONBLOCKING_IO && inputReady (ptr,0) != 1 )
-      return FILEOBJ_BLOCKED_READ;
-
     while ( (count = 
               (
-#ifdef HAVE_WINSOCK_H
+#ifdef USE_WINSOCK
                 fo->flags & FILEOBJ_WINSOCK ?
                 recv(fo->fd, &c, 1, 0) :
                 read(fo->fd, &c, 1))) <= 0 ) {