2 * (c) The GRASP/AQUA Project, Glasgow University, 1994-1998
4 * $Id: writeFile.c,v 1.3 1998/12/02 13:28:07 simonm Exp $
6 * hPutStr Runtime Support
13 writeFileObject(ptr, bytes)
18 IOFileObject* fo = (IOFileObject*)ptr;
20 char *p = (char *) fo->buf;
22 /* If we've got a r/w file object in our hand, flush the
23 (input) buffer contents first.
25 if ( FILEOBJ_READABLE(fo) && FILEOBJ_JUST_READ(fo) ) {
26 fo->flags = (fo->flags & ~FILEOBJ_RW_READ) | FILEOBJ_RW_WRITE;
27 rc = flushReadBuffer(ptr);
28 if (rc < 0) return rc;
31 return (writeBuffer(ptr, bytes));
35 writeBuffer(ptr, bytes)
40 IOFileObject* fo = (IOFileObject*)ptr;
42 char *p = (char *) fo->buf;
44 /* Disallow short writes */
45 if (bytes == 0 || fo->buf == NULL)
48 if ( fo->flags & FILEOBJ_NONBLOCKING_IO && inputReady(ptr,0) != 1 )
49 return FILEOBJ_BLOCKED_WRITE;
51 while ((count = write(fo->fd, fo->buf, bytes)) < bytes) {
60 /* Signal that we've emptied the buffer */
67 writeBuf(ptr, buf, len)
72 IOFileObject* fo = (IOFileObject*)ptr;
75 char *p = (char *) buf;
80 /* First of all, check if we do need to flush the buffer .. */
81 /* Note - in the case of line buffering, we do not currently check
82 whether we need to flush buffer due to line terminators in the
83 buffer we're outputting */
84 if ( fo->buf != NULL && /* buffered and */
85 (fo->bufWPtr + len < (fo->bufSize)) /* there's room */
87 /* Block copying is likely to be cheaper than, flush, followed by write */
88 memcpy(((char*)fo->buf + fo->bufWPtr), buf, len);
92 /* If we do overflow, flush current contents of the buffer and
93 directly output the chunk.
94 (no attempt at splitting up the chunk is currently made)
96 if ( fo->buf != NULL && /* buffered and */
97 (fo->bufWPtr + len >= (fo->bufSize)) /* there's not room */
100 rc = writeFileObject(ptr, fo->bufWPtr);
101 /* ToDo: undo buffer fill if we're blocking.. */
108 if ( fo->flags & FILEOBJ_NONBLOCKING_IO && inputReady(ptr,0) != 1 )
109 return FILEOBJ_BLOCKED_WRITE;
111 /* Disallow short writes */
112 while ((count = write(fo->fd, (char *)buf, (int)len)) < len) {
113 if (errno != EINTR) {
126 writeBufBA(ptr, buf, len)
130 { return (writeBuf(ptr,(StgAddr)buf, len)); }