[project @ 1999-09-19 19:20:50 by sof]
authorsof <unknown>
Sun, 19 Sep 1999 19:20:50 +0000 (19:20 +0000)
committersof <unknown>
Sun, 19 Sep 1999 19:20:50 +0000 (19:20 +0000)
* drop the restriction that seeks cannot be made on devices & beyond
  EOFs. If the underlying lseek() doesn't like us doing either, it'll
  let us know.
* When asking for the current position under Win32, take into account
  that lseek() reports the _untranslated_ position, so adjust the resulting
  position by scanning input buffer looking for \n's (and treat them
  as if \r\n.)

ghc/lib/std/cbits/filePosn.c

index fefdaf6..c3b130b 100644 (file)
@@ -1,7 +1,7 @@
 /* 
  * (c) The GRASP/AQUA Project, Glasgow University, 1994-1998
  *
- * $Id: filePosn.c,v 1.3 1998/12/02 13:27:27 simonm Exp $
+ * $Id: filePosn.c,v 1.4 1999/09/19 19:20:50 sof Exp $
  *
  * hGetPosn and hSetPosn Runtime Support
  */
@@ -14,7 +14,7 @@ getFilePosn(ptr)
 StgForeignPtr ptr;
 {
     IOFileObject* fo = (IOFileObject*)ptr;
-    StgInt posn;
+    off_t posn;
    
     while ( (posn = lseek(fo->fd, 0, SEEK_CUR)) == -1) {
        if (errno != EINTR) {
@@ -27,25 +27,66 @@ StgForeignPtr ptr;
        posn += fo->bufWPtr;
     } else if (fo->flags & FILEOBJ_READ) {
        posn -= (fo->bufWPtr - fo->bufRPtr);
+#if defined(_WIN32)
+       if (!(fo->flags & FILEOBJ_BINARY)) {
+         /* Sigh, to get at the Real file position for files opened
+            in text mode, we need to scan the read buffer looking for
+            '\n's, making them count as \r\n (i.e., undoing the work of
+             read()), since lseek() returns the raw position.
+         */
+          int i, j;
+         i = fo->bufRPtr;
+         j = fo->bufWPtr;
+          while (i <= j) {
+           if (((char*)fo->buf)[i] == '\n') {
+              posn--;
+           }
+           i++;
+         }
+       }
+#endif
     }
-    return posn;
+    return (StgInt)posn;
 }
 
 /* The following is only called with a position that we've already visited 
    (this is ensured by making the Haskell file posn. type abstract.)
 */
 StgInt
-setFilePosn(ptr, posn)
+setFilePosn(ptr, size, d)
 StgForeignPtr ptr;
-StgInt posn;
+StgInt size;
+StgByteArray d;
 {
     IOFileObject* fo = (IOFileObject*)ptr;
-    int rc;
+    int rc, mode;
+    off_t offset;
+
+    /*
+     * We need to snatch the offset out of an MP_INT.  The bits are there sans sign,
+     * which we pick up from our size parameter.  If abs(size) is greater than 1,
+     * this integer is just too big.
+     */
+    switch (size) {
+    case -1:
+       offset = -*(StgInt *) d;
+       break;
+    case 0:
+       offset = 0;
+       break;
+    case 1:
+       offset = *(StgInt *) d;
+       break;
+    default:
+       ghc_errtype = ERR_INVALIDARGUMENT;
+       ghc_errstr = "offset out of range";
+       return -1;
+    }
 
     rc = flushBuffer(ptr);
     if (rc < 0) return rc;
 
-    while (lseek(fo->fd, posn, SEEK_SET) == -1) {
+    while (lseek(fo->fd, offset, SEEK_SET) == -1) {
        if (errno != EINTR) {
            cvtErrno();
            stdErrno();