diff options
author | simonmar <unknown> | 2001-05-18 16:54:11 +0000 |
---|---|---|
committer | simonmar <unknown> | 2001-05-18 16:54:11 +0000 |
commit | d9af408e5c512501cfa991f5e4a76c9154bca917 (patch) | |
tree | 627365b7dad9c2a5e1d892a1f631690b46e24a11 /ghc/lib/std/cbits/fileObject.c | |
parent | 5f6f90850d5c82dc56d13bbc035d635e1cb2106b (diff) | |
download | haskell-d9af408e5c512501cfa991f5e4a76c9154bca917.tar.gz |
[project @ 2001-05-18 16:54:04 by simonmar]
I/O library rewrite
-------------------
This commit replaces the old C/Haskell I/O implementation with a new
Haskell-only one using the new FFI & hsc2hs.
main points:
- lots of code deleted: we're about 3000 lines of C lighter,
but the amount of Haskell code is about the same.
- performance is ok: some operations are faster, others are
slower. There's still some tuning to do, though.
- the new library is designed to handle read/write streams
much better: a read/write stream gets a special kind of
handle internally called a "DuplexHandle", which actually
contains two separate handles, one for writing and one for
reading. The upshot is that you can do simultaneous reading
and writing to/from a socket or FIFO without any locking
problems. The effect is similar to calling socketToHandle
twice, except that finalization works properly (creating
two separate Handles could lead to the socket being closed
too early when one of the Handles is GC'd).
- hConnectTo and withHandleFor are gone (no one responded to
my mail on GHC users, but we can always bring 'em back if
necessary).
- I made a half-hearted attempt at keeping the system-specific
code in one place: see PrelPosix.hsc.
- I've rearranged the I/O tests and added lots more.
ghc/tests/lib/IO now contains Haskell 98-only IO tests,
ghc/test/lib/{IOExts, Directory, Time} now contain tests for
the relevant libraries. I haven't quite finished in here yet,
the IO tests work but the others don't yet.
- I haven't done anything about Unicode yet, but now we can
start to discuss what needs doing here. The new library
is using MutableByteArrays for its buffers because that
turned out to be a *lot* easier (and quicker) than malloc'd
buffers - I hope this won't cause trouble for unicode
translations though.
WARNING: Windows users refrain from updating until we've had a chance
to fix any issues that arise.
Testing: the basic H98 stuff has been pretty thoroughly tested, but
the new duplex handle stuff is still a little green.
Diffstat (limited to 'ghc/lib/std/cbits/fileObject.c')
-rw-r--r-- | ghc/lib/std/cbits/fileObject.c | 160 |
1 files changed, 0 insertions, 160 deletions
diff --git a/ghc/lib/std/cbits/fileObject.c b/ghc/lib/std/cbits/fileObject.c deleted file mode 100644 index 20c0ab3f0d..0000000000 --- a/ghc/lib/std/cbits/fileObject.c +++ /dev/null @@ -1,160 +0,0 @@ -/* - * (c) The GRASP/AQUA Project, Glasgow University, 1994-1998 - * - * $Id: fileObject.c,v 1.11 2000/10/10 09:28:50 simonmar Exp $ - * - * hPutStr Runtime Support - */ - -#include "Rts.h" -#include "stgio.h" - -#include <stdio.h> - -#if defined(HAVE_WINSOCK_H) && !defined(__CYGWIN__) && !defined(__CYGWIN32__) -#define USE_WINSOCK -#endif - -#ifdef USE_WINSOCK -#include <winsock.h> -#endif - -void -setBufFlags(StgForeignPtr fo, StgInt flg) -{ - ((IOFileObject*)fo)->flags = flg; - return; -} - -void -setBufWPtr(StgForeignPtr fo, StgInt len) -{ - ((IOFileObject*)fo)->bufWPtr = len; - return; -} - -StgInt -getBufWPtr(StgForeignPtr fo) -{ - return (((IOFileObject*)fo)->bufWPtr); -} - -StgInt -getBufSize(StgForeignPtr fo) -{ - return (((IOFileObject*)fo)->bufSize); -} - -void -setBuf(StgForeignPtr fo, StgAddr buf,StgInt sz) -{ - ((IOFileObject*)fo)->buf = buf; - ((IOFileObject*)fo)->bufSize = sz; - return; -} - -StgAddr -getBuf(StgForeignPtr fo) -{ return (((IOFileObject*)fo)->buf); } - -StgAddr -getWriteableBuf(StgForeignPtr ptr) -{ - /* getWriteableBuf() is called prior to starting to pack - a Haskell string into the IOFileObject buffer. It takes - care of flushing the (input) buffer in the case we're - dealing with a RW handle. - */ - IOFileObject* fo = (IOFileObject*)ptr; - - if ( FILEOBJ_READABLE(fo) && FILEOBJ_JUST_READ(fo) ) { - flushReadBuffer(ptr); /* ignoring return code */ - /* Ahead of time really, but indicate that we're (just about to) write */ - } - fo->flags = (fo->flags & ~FILEOBJ_RW_READ) | FILEOBJ_RW_WRITE; - return (fo->buf); -} - -StgAddr -getBufStart(StgForeignPtr fo, StgInt count) -{ return ((char*)((IOFileObject*)fo)->buf + (((IOFileObject*)fo)->bufRPtr) - count); } - -StgInt -getFileFd(StgForeignPtr fo) -{ return (((IOFileObject*)fo)->fd); } - -StgInt -getConnFileFd(StgForeignPtr fo) -{ return (((IOFileObject*)fo)->connectedTo->fd); } - - -void -setFd(StgForeignPtr fo,StgInt fp) -{ ((IOFileObject*)fo)->fd = fp; - return; -} - -void -setConnectedTo(StgForeignPtr fo, StgForeignPtr fw, StgInt flg) -{ - if( flg && (! isatty(((IOFileObject*)fo)->fd) || !isatty(((IOFileObject*)fw)->fd)) ) { - return; - } - ((IOFileObject*)fo)->connectedTo = (IOFileObject*)fw; - return; -} - -static int __pushback_buf_size__ = 2; - -void -setPushbackBufSize(StgInt i) -{ __pushback_buf_size__ = (i > 0 ? i : 0); } - -StgInt -getPushbackBufSize(void) -{ return (__pushback_buf_size__); } - -/* Only ever called on line-buffered file objects */ -StgInt -fill_up_line_buffer(IOFileObject* fo) -{ - int count,len, ipos; - unsigned char* p; - - /* ToDo: deal with buffer overflow (i.e., realloc buffer if this happens) */ - - if ( fo->bufRPtr == fo->bufWPtr ) { /* There's nothing in the buffer, reset */ - fo->bufRPtr=0; - fo->bufWPtr=0; - } - ipos = fo->bufWPtr; - len = fo->bufSize - fo->bufWPtr; - p = (unsigned char*)fo->buf + fo->bufWPtr; - - while ((count = - ( -#ifdef USE_WINSOCK - fo->flags & FILEOBJ_WINSOCK ? - recv(fo->fd, p, len, 0) : - read(fo->fd, p, len))) <= 0 ) { -#else - read(fo->fd, p, len))) <= 0 ) { -#endif - if (count == 0) { - ghc_errtype = ERR_EOF; - ghc_errstr = ""; - FILEOBJ_SET_EOF(fo); - return -1; - } else if ( count == -1 && errno == EAGAIN) { - errno = 0; - return FILEOBJ_BLOCKED_READ; - } else if ( count == -1 && errno != EINTR ) { - cvtErrno(); - stdErrno(); - return -1; - } - } - fo->bufWPtr += count; -/* TODO: ipos doesn't change???? what's it for??? --SDM */ - return (fo->bufWPtr - ipos); -} |