From ecdc4ca6c18d7ec2160ec104b9c94dbcb866ef9d Mon Sep 17 00:00:00 2001
From: sof <unknown>
Date: Sun, 19 Sep 1999 19:20:50 +0000
Subject: [PATCH] [project @ 1999-09-19 19:20:50 by sof] * 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 | 55 +++++++++++++++++++++++++++++++-----
 1 file changed, 48 insertions(+), 7 deletions(-)

diff --git a/ghc/lib/std/cbits/filePosn.c b/ghc/lib/std/cbits/filePosn.c
index fefdaf6ea22a..c3b130b063ae 100644
--- a/ghc/lib/std/cbits/filePosn.c
+++ b/ghc/lib/std/cbits/filePosn.c
@@ -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();
-- 
GitLab