diff options
author | sof <unknown> | 1999-09-19 19:20:50 +0000 |
---|---|---|
committer | sof <unknown> | 1999-09-19 19:20:50 +0000 |
commit | ecdc4ca6c18d7ec2160ec104b9c94dbcb866ef9d (patch) | |
tree | 57972000aa91bdff25d8e796376e55659461ec1d /ghc/lib/std/cbits/filePosn.c | |
parent | 8e0fd8c71316d1d5a5d66e51550020f82a0b46ea (diff) | |
download | haskell-ecdc4ca6c18d7ec2160ec104b9c94dbcb866ef9d.tar.gz |
[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.)
Diffstat (limited to 'ghc/lib/std/cbits/filePosn.c')
-rw-r--r-- | ghc/lib/std/cbits/filePosn.c | 55 |
1 files changed, 48 insertions, 7 deletions
diff --git a/ghc/lib/std/cbits/filePosn.c b/ghc/lib/std/cbits/filePosn.c index fefdaf6ea2..c3b130b063 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(); |