2 * (c) The GRASP/AQUA Project, Glasgow University, 1994-1998
4 * $Id: writeFile.c,v 1.11 1999/11/26 16:25:57 simonmar Exp $
6 * hPutStr Runtime Support
12 #if defined(HAVE_WINSOCK_H) && !defined(__CYGWIN__) && !defined(__CYGWIN32__)
21 writeFileObject(StgForeignPtr ptr, StgInt bytes)
24 IOFileObject* fo = (IOFileObject*)ptr;
26 char *p = (char *) fo->buf;
28 /* If we've got a r/w file object in our hand, flush the
29 (input) buffer contents first.
31 if ( FILEOBJ_READABLE(fo) && FILEOBJ_JUST_READ(fo) ) {
32 fo->flags = (fo->flags & ~FILEOBJ_RW_READ) | FILEOBJ_RW_WRITE;
33 rc = flushReadBuffer(ptr);
34 if (rc < 0) return rc;
37 return (writeBuffer(ptr, bytes));
41 writeBuffer(StgForeignPtr ptr, StgInt bytes)
44 IOFileObject* fo = (IOFileObject*)ptr;
46 char *pBuf = (char *) fo->buf + fo->bufStart;
48 bytes -= fo->bufStart;
50 /* Disallow short writes */
51 if (bytes == 0 || fo->buf == NULL) {
59 fo->flags & FILEOBJ_WINSOCK ?
60 send(fo->fd, pBuf, bytes, 0) :
61 write(fo->fd, pBuf, bytes))) < bytes) {
63 write(fo->fd, pBuf, bytes))) < bytes) {
65 if ( count == -1 && errno == EAGAIN) {
67 return FILEOBJ_BLOCKED_WRITE;
69 else if ( count == -1 && errno != EINTR ) {
77 fo->bufStart += count;
80 /* Signal that we've emptied the buffer */
88 writeBuf(StgForeignPtr ptr, StgAddr buf, StgInt len)
90 IOFileObject* fo = (IOFileObject*)ptr;
93 char *pBuf = (char *) buf;
98 /* First of all, check if we do need to flush the buffer .. */
99 /* Note - in the case of line buffering, we do not currently check
100 whether we need to flush buffer due to line terminators in the
101 buffer we're outputting */
102 if ( fo->buf != NULL && /* buffered and */
103 (fo->bufWPtr + len < (fo->bufSize)) /* there's room */
105 /* Block copying is likely to be cheaper than, flush, followed by write */
106 memcpy(((char*)fo->buf + fo->bufWPtr), buf, len);
110 /* If we do overflow, flush current contents of the buffer and
111 directly output the chunk.
112 (no attempt at splitting up the chunk is currently made)
114 if ( fo->buf != NULL && /* buffered and */
115 (fo->bufWPtr + len >= (fo->bufSize)) /* there's not room */
118 rc = writeFileObject(ptr, fo->bufWPtr);
119 /* ToDo: undo buffer fill if we're blocking.. */
128 fo->flags & FILEOBJ_WINSOCK ?
129 send(fo->fd, pBuf, (int)len, 0) :
130 write(fo->fd, pBuf, (int)len))) < len ) {
132 write(fo->fd, pBuf, (int)len))) < len ) {
138 } else if ( errno == EAGAIN ) {
140 return FILEOBJ_BLOCKED_WRITE;
141 } else if ( errno != EINTR ) {
152 writeBufBA(StgForeignPtr ptr, StgByteArray buf, StgInt len)
154 return (writeBuf(ptr,(StgAddr)buf, len));