summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsimonmar <unknown>1999-11-25 16:54:15 +0000
committersimonmar <unknown>1999-11-25 16:54:15 +0000
commit0086477cfe554f9c65ae4c2f1e4e19f4e8c063eb (patch)
tree506ffebc9496dc64bbc5cf129eea5c2ebbd533c6
parent63b4f50cfaa383118c947445e5afb4fff3cd1c91 (diff)
downloadhaskell-0086477cfe554f9c65ae4c2f1e4e19f4e8c063eb.tar.gz
[project @ 1999-11-25 16:54:14 by simonmar]
Incremental cleanups & improvements to the I/O subsystem - Initial fix for problems caused by partial writes to non-blocking file descriptors. To see this bug, run ghc/tests/programs/life_space_leak through a pipe. - remove FILEOBJ_FLUSH, it allegedly has the same meaning as FILEOBJ_WRITE. This fixes a buf in openFd: it erroneously didn't set FILEOBJ_FLUSH on writeable file descriptors. - some ANSIfication
-rw-r--r--ghc/lib/std/cbits/allocMem.c5
-rw-r--r--ghc/lib/std/cbits/closeFile.c8
-rw-r--r--ghc/lib/std/cbits/fileEOF.c5
-rw-r--r--ghc/lib/std/cbits/fileLookAhead.c9
-rw-r--r--ghc/lib/std/cbits/fileObject.h14
-rw-r--r--ghc/lib/std/cbits/filePutc.c6
-rw-r--r--ghc/lib/std/cbits/flushFile.c16
-rw-r--r--ghc/lib/std/cbits/freeFile.c27
-rw-r--r--ghc/lib/std/cbits/openFile.c27
-rw-r--r--ghc/lib/std/cbits/setBuffering.c4
-rw-r--r--ghc/lib/std/cbits/writeFile.c44
11 files changed, 82 insertions, 83 deletions
diff --git a/ghc/lib/std/cbits/allocMem.c b/ghc/lib/std/cbits/allocMem.c
index f159cfdf5a..609e8828e9 100644
--- a/ghc/lib/std/cbits/allocMem.c
+++ b/ghc/lib/std/cbits/allocMem.c
@@ -1,7 +1,7 @@
/*
* (c) The GRASP/AQUA Project, Glasgow University, 1994-1998
*
- * $Id: allocMem.c,v 1.2 1998/12/02 13:27:13 simonm Exp $
+ * $Id: allocMem.c,v 1.3 1999/11/25 16:54:14 simonmar Exp $
*
* malloc interface
*/
@@ -10,8 +10,7 @@
#include "stgio.h"
StgAddr
-allocMemory__(sz)
-StgInt sz;/* bytes*/
+allocMemory__(StgInt sz/* bytes */)
{
StgAddr ptr;
diff --git a/ghc/lib/std/cbits/closeFile.c b/ghc/lib/std/cbits/closeFile.c
index 1e94d80a0f..1addd3f3dd 100644
--- a/ghc/lib/std/cbits/closeFile.c
+++ b/ghc/lib/std/cbits/closeFile.c
@@ -1,7 +1,7 @@
/*
* (c) The GRASP/AQUA Project, Glasgow University, 1994-1998
*
- * $Id: closeFile.c,v 1.6 1999/07/12 10:43:12 sof Exp $
+ * $Id: closeFile.c,v 1.7 1999/11/25 16:54:14 simonmar Exp $
*
* hClose Runtime Support
*/
@@ -20,9 +20,7 @@
StgInt __really_close_stdfiles=1;
StgInt
-closeFile(ptr,flush_buf)
-StgForeignPtr ptr;
-StgInt flush_buf;
+closeFile(StgForeignPtr ptr, StgInt flush_buf)
{
IOFileObject* fo = (IOFileObject*)ptr;
int rc = 0;
@@ -33,7 +31,7 @@ StgInt flush_buf;
return 0;
}
- if ( flush_buf != 0 && (fo->flags & FILEOBJ_FLUSH) ) {
+ if ( flush_buf != 0 && (fo->flags & FILEOBJ_WRITE) ) {
writeFileObject(ptr,fo->bufWPtr);
}
diff --git a/ghc/lib/std/cbits/fileEOF.c b/ghc/lib/std/cbits/fileEOF.c
index 746a2a9670..ac0f11451e 100644
--- a/ghc/lib/std/cbits/fileEOF.c
+++ b/ghc/lib/std/cbits/fileEOF.c
@@ -1,7 +1,7 @@
/*
* (c) The GRASP/AQUA Project, Glasgow University, 1994-1998
*
- * $Id: fileEOF.c,v 1.3 1998/12/02 13:27:22 simonm Exp $
+ * $Id: fileEOF.c,v 1.4 1999/11/25 16:54:14 simonmar Exp $
*
* hIsEOF Runtime Support
*/
@@ -10,8 +10,7 @@
#include "stgio.h"
StgInt
-fileEOF(ptr)
-StgForeignPtr ptr;
+fileEOF(StgForeignPtr ptr)
{
IOFileObject* fo = (IOFileObject*)ptr;
diff --git a/ghc/lib/std/cbits/fileLookAhead.c b/ghc/lib/std/cbits/fileLookAhead.c
index 60267df647..aa47301d6a 100644
--- a/ghc/lib/std/cbits/fileLookAhead.c
+++ b/ghc/lib/std/cbits/fileLookAhead.c
@@ -1,7 +1,7 @@
/*
* (c) The GRASP/AQUA Project, Glasgow University, 1994-1998
*
- * $Id: fileLookAhead.c,v 1.3 1998/12/02 13:27:25 simonm Exp $
+ * $Id: fileLookAhead.c,v 1.4 1999/11/25 16:54:14 simonmar Exp $
*
* hLookAhead Runtime Support
*/
@@ -10,8 +10,7 @@
#include "stgio.h"
StgInt
-fileLookAhead(ptr)
-StgForeignPtr ptr;
+fileLookAhead(StgForeignPtr ptr)
{
IOFileObject* fo = (IOFileObject*)ptr;
int c, rc;
@@ -45,9 +44,7 @@ StgForeignPtr ptr;
}
StgInt
-ungetChar(ptr,c)
-StgForeignPtr ptr;
-StgChar c;
+ungetChar(StgForeignPtr ptr, StgChar c)
{
IOFileObject* fo = (IOFileObject*)ptr;
int rc = 0, sz = 0;
diff --git a/ghc/lib/std/cbits/fileObject.h b/ghc/lib/std/cbits/fileObject.h
index deca1b0cc5..4c36977a5a 100644
--- a/ghc/lib/std/cbits/fileObject.h
+++ b/ghc/lib/std/cbits/fileObject.h
@@ -13,6 +13,19 @@
typedef struct _IOFileObject {
int fd;
void* buf;
+
+ int bufStart; /* offset of start of data waiting to
+ be written. This may be non-zero in
+ the case where we wrote out some of the
+ buffer, and then blocked.
+
+ NOTE: this field should be non-zero *only*
+ when we just blocked on a call to writeBuffer,
+ and we're going to restart the call when
+ we unblock. It should be zero at all other
+ times.
+ */
+
int bufWPtr; /* points to next position to write,
bufRPtr >= bufWPtr <= bufSize.
@@ -33,7 +46,6 @@ typedef struct _IOFileObject {
struct _IOFileObject* connectedTo;
} IOFileObject;
-#define FILEOBJ_FLUSH 1
#define FILEOBJ_LB 2
#define FILEOBJ_BB 4
#define FILEOBJ_EOF 8
diff --git a/ghc/lib/std/cbits/filePutc.c b/ghc/lib/std/cbits/filePutc.c
index b48f9fe8fd..f2ce4a9c30 100644
--- a/ghc/lib/std/cbits/filePutc.c
+++ b/ghc/lib/std/cbits/filePutc.c
@@ -1,7 +1,7 @@
/*
* (c) The GRASP/AQUA Project, Glasgow University, 1994-1998
*
- * $Id: filePutc.c,v 1.8 1999/09/16 13:14:43 simonmar Exp $
+ * $Id: filePutc.c,v 1.9 1999/11/25 16:54:14 simonmar Exp $
*
* hPutChar Runtime Support
*/
@@ -21,9 +21,7 @@
#define TERMINATE_LINE(x) ((x) == '\n')
StgInt
-filePutc(ptr, c)
-StgForeignPtr ptr;
-StgChar c;
+filePutc(StgForeignPtr ptr, StgChar c)
{
IOFileObject* fo = (IOFileObject*)ptr;
int rc = 0;
diff --git a/ghc/lib/std/cbits/flushFile.c b/ghc/lib/std/cbits/flushFile.c
index 190d78a465..4416559a33 100644
--- a/ghc/lib/std/cbits/flushFile.c
+++ b/ghc/lib/std/cbits/flushFile.c
@@ -1,7 +1,7 @@
/*
* (c) The GRASP/AQUA Project, Glasgow University, 1994-1998
*
- * $Id: flushFile.c,v 1.5 1999/09/19 19:26:14 sof Exp $
+ * $Id: flushFile.c,v 1.6 1999/11/25 16:54:14 simonmar Exp $
*
* hFlush Runtime Support
*/
@@ -10,13 +10,12 @@
#include "stgio.h"
StgInt
-flushFile(ptr)
-StgForeignPtr ptr;
+flushFile(StgForeignPtr ptr)
{
IOFileObject* fo = (IOFileObject*)ptr;
int rc = 0;
- if ( (fo->flags & FILEOBJ_FLUSH) && FILEOBJ_NEEDS_FLUSHING(fo) ) {
+ if ( (fo->flags & FILEOBJ_WRITE) && FILEOBJ_NEEDS_FLUSHING(fo) ) {
rc = writeBuffer(ptr,fo->bufWPtr - fo->bufRPtr);
}
@@ -24,8 +23,7 @@ StgForeignPtr ptr;
}
StgInt
-flushBuffer(ptr)
-StgForeignPtr ptr;
+flushBuffer(StgForeignPtr ptr)
{
IOFileObject* fo = (IOFileObject*)ptr;
int rc = 0;
@@ -57,8 +55,7 @@ StgForeignPtr ptr;
the solution of leaving this to the programmer!)
*/
StgInt
-flushReadBuffer(ptr)
-StgForeignPtr ptr;
+flushReadBuffer(StgForeignPtr ptr)
{
IOFileObject* fo = (IOFileObject*)ptr;
int delta;
@@ -81,8 +78,7 @@ StgForeignPtr ptr;
}
void
-flushConnectedBuf(ptr)
-StgForeignPtr ptr;
+flushConnectedBuf(StgForeignPtr ptr)
{
StgInt rc;
IOFileObject* fo = (IOFileObject*)ptr;
diff --git a/ghc/lib/std/cbits/freeFile.c b/ghc/lib/std/cbits/freeFile.c
index a03a661c9f..aaf492f15a 100644
--- a/ghc/lib/std/cbits/freeFile.c
+++ b/ghc/lib/std/cbits/freeFile.c
@@ -1,7 +1,7 @@
/*
* (c) The GRASP/AQUA Project, Glasgow University, 1994-1998
*
- * $Id: freeFile.c,v 1.6 1999/07/12 10:43:13 sof Exp $
+ * $Id: freeFile.c,v 1.7 1999/11/25 16:54:14 simonmar Exp $
*
* Giving up files
*/
@@ -24,26 +24,29 @@
ForeignObj finaliser, as we probably want to use these
before we *really* shut down (dumping stats etc.)
*/
-void freeStdFile(fp)
-StgForeignPtr fp;
+void
+freeStdFile(StgForeignPtr fp)
{ return; }
-void freeStdFileObject(ptr)
-StgForeignPtr ptr;
+void
+freeStdFileObject(StgForeignPtr ptr)
{
IOFileObject* fo = (IOFileObject*)ptr;
+ int rc;
/* Don't close the file, just flush the buffer */
if (fo != NULL && fo->fd != -1) {
- if (fo->buf != NULL && (fo->flags & FILEOBJ_FLUSH) && fo->bufWPtr > 0) {
+ if (fo->buf != NULL && (fo->flags & FILEOBJ_WRITE) && fo->bufWPtr > 0) {
/* Flush buffer contents */
- writeBuffer((StgForeignPtr)fo, fo->bufWPtr);
+ do {
+ rc = writeBuffer((StgForeignPtr)fo, fo->bufWPtr);
+ } while (rc == FILEOBJ_BLOCKED_WRITE) ;
}
}
}
-void freeFileObject(ptr)
-StgForeignPtr ptr;
+void
+freeFileObject(StgForeignPtr ptr)
{
/*
* The finaliser for the file objects embedded in Handles. The RTS
@@ -85,12 +88,14 @@ StgForeignPtr ptr;
return;
}
-StgAddr ref_freeStdFileObject(void)
+StgAddr
+ref_freeStdFileObject(void)
{
return (StgAddr)&freeStdFileObject;
}
-StgAddr ref_freeFileObject(void)
+StgAddr
+ref_freeFileObject(void)
{
return (StgAddr)&freeFileObject;
}
diff --git a/ghc/lib/std/cbits/openFile.c b/ghc/lib/std/cbits/openFile.c
index 2491b179ac..d1b0d6d53e 100644
--- a/ghc/lib/std/cbits/openFile.c
+++ b/ghc/lib/std/cbits/openFile.c
@@ -1,7 +1,7 @@
/*
* (c) The GRASP/AQUA Project, Glasgow University, 1994-1998
*
- * $Id: openFile.c,v 1.10 1999/09/30 12:35:04 sof Exp $
+ * $Id: openFile.c,v 1.11 1999/11/25 16:54:14 simonmar Exp $
*
* openFile Runtime Support
*/
@@ -47,7 +47,7 @@ StgInt rd;
fo->buf = NULL;
fo->bufWPtr = 0;
fo->bufRPtr = 0;
- fo->flags = FILEOBJ_STD | ( rd ? FILEOBJ_READ : (FILEOBJ_WRITE | FILEOBJ_FLUSH));
+ fo->flags = FILEOBJ_STD | ( rd ? FILEOBJ_READ : FILEOBJ_WRITE);
fo->connectedTo = NULL;
/* MS Win32 CRT doesn't support fcntl() -- the workaround is to
@@ -96,11 +96,11 @@ StgInt binary;
case OPENFILE_APPEND:
oflags = O_NONBLOCK | O_WRONLY | O_NOCTTY | O_APPEND;
for_writing = 1;
- flags |= FILEOBJ_WRITE | FILEOBJ_FLUSH;
+ flags |= FILEOBJ_WRITE;
break;
case OPENFILE_WRITE:
oflags = O_NONBLOCK | O_WRONLY | O_NOCTTY;
- flags |= FILEOBJ_WRITE | FILEOBJ_FLUSH;
+ flags |= FILEOBJ_WRITE;
for_writing = 1;
break;
case OPENFILE_READ_ONLY:
@@ -110,7 +110,7 @@ StgInt binary;
break;
case OPENFILE_READ_WRITE:
oflags = O_NONBLOCK | O_RDWR | O_NOCTTY;
- flags |= FILEOBJ_READ | FILEOBJ_WRITE | FILEOBJ_FLUSH;
+ flags |= FILEOBJ_READ | FILEOBJ_WRITE;
for_writing = 1;
break;
default:
@@ -280,6 +280,7 @@ StgInt binary;
fo->fd = fd;
fo->buf = NULL;
+ fo->bufStart = 0;
fo->bufWPtr = 0;
fo->bufRPtr = 0;
fo->flags = flags;
@@ -289,10 +290,7 @@ StgInt binary;
/* `Lock' file descriptor and return file object. */
IOFileObject*
-openFd(fd,oflags,flags)
-StgInt fd;
-StgInt oflags;
-StgInt flags;
+openFd(StgInt fd,StgInt oflags,StgInt flags)
{
int for_writing;
FILE* fp;
@@ -318,11 +316,12 @@ StgInt flags;
/* See openFileObject() comment */
if ((fo = malloc(sizeof(IOFileObject))) == NULL)
return NULL;
- fo->fd = fd;
- fo->buf = NULL;
- fo->bufWPtr = 0;
- fo->bufRPtr = 0;
- fo->flags = flags | ( oflags & O_RDONLY ? FILEOBJ_READ
+ fo->fd = fd;
+ fo->buf = NULL;
+ fo->bufStart = 0;
+ fo->bufWPtr = 0;
+ fo->bufRPtr = 0;
+ fo->flags = flags | ( oflags & O_RDONLY ? FILEOBJ_READ
: oflags & O_RDWR ? FILEOBJ_READ
: 0)
| ( oflags & O_WRONLY ? FILEOBJ_WRITE
diff --git a/ghc/lib/std/cbits/setBuffering.c b/ghc/lib/std/cbits/setBuffering.c
index 7c77a7b8e9..1891de0fe7 100644
--- a/ghc/lib/std/cbits/setBuffering.c
+++ b/ghc/lib/std/cbits/setBuffering.c
@@ -1,7 +1,7 @@
/*
* (c) The GRASP/AQUA Project, Glasgow University, 1994-1998
*
- * $Id: setBuffering.c,v 1.5 1999/05/05 10:33:16 sof Exp $
+ * $Id: setBuffering.c,v 1.6 1999/11/25 16:54:15 simonmar Exp $
*
* hSetBuffering Runtime Support
*/
@@ -42,7 +42,7 @@ StgInt size;
/* First off, flush old buffer.. */
- if ( (fo->flags & FILEOBJ_FLUSH) ) {
+ if ( (fo->flags & FILEOBJ_WRITE) ) {
rc = flushBuffer(ptr);
}
if (rc<0) return rc;
diff --git a/ghc/lib/std/cbits/writeFile.c b/ghc/lib/std/cbits/writeFile.c
index 0c2f78fd0d..f5ae542671 100644
--- a/ghc/lib/std/cbits/writeFile.c
+++ b/ghc/lib/std/cbits/writeFile.c
@@ -1,7 +1,7 @@
/*
* (c) The GRASP/AQUA Project, Glasgow University, 1994-1998
*
- * $Id: writeFile.c,v 1.9 1999/11/05 15:25:49 simonmar Exp $
+ * $Id: writeFile.c,v 1.10 1999/11/25 16:54:15 simonmar Exp $
*
* hPutStr Runtime Support
*/
@@ -18,9 +18,7 @@
#endif
StgInt
-writeFileObject(ptr, bytes)
-StgForeignPtr ptr;
-StgInt bytes;
+writeFileObject(StgForeignPtr ptr, StgInt bytes)
{
int rc=0;
IOFileObject* fo = (IOFileObject*)ptr;
@@ -40,18 +38,20 @@ StgInt bytes;
}
StgInt
-writeBuffer(ptr, bytes)
-StgForeignPtr ptr;
-StgInt bytes;
+writeBuffer(StgForeignPtr ptr, StgInt bytes)
{
int count, rc=0;
IOFileObject* fo = (IOFileObject*)ptr;
- char *pBuf = (char *) fo->buf;
+ char *pBuf = (char *) fo->buf + fo->bufStart;
+
+ bytes -= fo->bufStart;
/* Disallow short writes */
- if (bytes == 0 || fo->buf == NULL)
+ if (bytes == 0 || fo->buf == NULL) {
+ fo->bufStart = 0;
return 0;
+ }
while ((count =
(
@@ -74,19 +74,18 @@ StgInt bytes;
else {
bytes -= count;
pBuf += count;
+ fo->bufStart += count;
}
}
/* Signal that we've emptied the buffer */
- fo->bufWPtr=0;
+ fo->bufStart = 0;
+ fo->bufWPtr = 0;
return 0;
}
StgInt
-writeBuf(ptr, buf, len)
-StgForeignPtr ptr;
-StgAddr buf;
-StgInt len;
+writeBuf(StgForeignPtr ptr, StgAddr buf, StgInt len)
{
IOFileObject* fo = (IOFileObject*)ptr;
int count;
@@ -117,11 +116,9 @@ StgInt len;
) {
/* Flush buffer */
rc = writeFileObject(ptr, fo->bufWPtr);
- /* ToDo: undo buffer fill if we're blocking.. */
- }
-
- if (rc != 0) {
- return rc;
+ if (rc != 0) {
+ return rc;
+ }
}
while ((count =
@@ -151,8 +148,7 @@ StgInt len;
}
StgInt
-writeBufBA(ptr, buf, len)
- StgForeignPtr ptr;
-StgByteArray buf;
-StgInt len;
-{ return (writeBuf(ptr,(StgAddr)buf, len)); }
+writeBufBA(StgForeignPtr ptr, StgByteArray buf, StgInt len)
+{
+ return (writeBuf(ptr,(StgAddr)buf, len));
+}