/*
* (c) The GRASP/AQUA Project, Glasgow University, 1994-1998
*
- * $Id: writeFile.c,v 1.3 1998/12/02 13:28:07 simonm Exp $
+ * $Id: writeFile.c,v 1.12 1999/12/08 15:47:08 simonmar Exp $
*
* hPutStr Runtime Support
*/
#include "Rts.h"
#include "stgio.h"
+#if defined(HAVE_WINSOCK_H) && !defined(__CYGWIN__) && !defined(__CYGWIN32__)
+#define USE_WINSOCK
+#endif
+
+#ifdef USE_WINSOCK
+#include <winsock.h>
+#endif
+
StgInt
-writeFileObject(ptr, bytes)
-StgForeignPtr ptr;
-StgInt bytes;
+writeFileObject(StgForeignPtr ptr, StgInt bytes)
{
int rc=0;
IOFileObject* fo = (IOFileObject*)ptr;
- char *p = (char *) fo->buf;
-
/* If we've got a r/w file object in our hand, flush the
(input) buffer contents first.
*/
}
StgInt
-writeBuffer(ptr, bytes)
-StgForeignPtr ptr;
-StgInt bytes;
+writeBuffer(StgForeignPtr ptr, StgInt bytes)
{
- int count, rc=0;
+ int count;
IOFileObject* fo = (IOFileObject*)ptr;
- char *p = (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;
+ }
- if ( fo->flags & FILEOBJ_NONBLOCKING_IO && inputReady(ptr,0) != 1 )
- return FILEOBJ_BLOCKED_WRITE;
-
- while ((count = write(fo->fd, fo->buf, bytes)) < bytes) {
- if (errno != EINTR) {
+ while ((count =
+ (
+#ifdef USE_WINSOCK
+ fo->flags & FILEOBJ_WINSOCK ?
+ send(fo->fd, pBuf, bytes, 0) :
+ write(fo->fd, pBuf, bytes))) < bytes) {
+#else
+ write(fo->fd, pBuf, bytes))) < bytes) {
+#endif
+ if ( count == -1 && errno == EAGAIN) {
+ errno = 0;
+ return FILEOBJ_BLOCKED_WRITE;
+ }
+ else if ( count == -1 && errno != EINTR ) {
cvtErrno();
stdErrno();
return -1;
}
- bytes -= count;
- p += count;
+ 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;
int rc = 0;
- char *p = (char *) buf;
+ char *pBuf = (char *) buf;
if (len == 0 )
return 0;
/* 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;
- }
-
- if ( fo->flags & FILEOBJ_NONBLOCKING_IO && inputReady(ptr,0) != 1 )
- return FILEOBJ_BLOCKED_WRITE;
-
- /* Disallow short writes */
- while ((count = write(fo->fd, (char *)buf, (int)len)) < len) {
- if (errno != EINTR) {
+ while ((count =
+ (
+#ifdef USE_WINSOCK
+ fo->flags & FILEOBJ_WINSOCK ?
+ send(fo->fd, pBuf, (int)len, 0) :
+ write(fo->fd, pBuf, (int)len))) < len ) {
+#else
+ write(fo->fd, pBuf, (int)len))) < len ) {
+#endif
+ if ( count >= 0 ) {
+ len -= count;
+ pBuf += count;
+ continue;
+ } else if ( errno == EAGAIN ) {
+ errno = 0;
+ return FILEOBJ_BLOCKED_WRITE;
+ } else if ( errno != EINTR ) {
cvtErrno();
stdErrno();
return -1;
}
- len -= count;
- p += count;
}
return 0;
}
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));
+}