From ecdc4ca6c18d7ec2160ec104b9c94dbcb866ef9d Mon Sep 17 00:00:00 2001 From: sof 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 fefdaf6..c3b130b 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(); -- 1.7.10.4