]> pd.if.org Git - pdclib/blobdiff - functions/_PDCLIB/fflush.c
Intermediate work, checked in for safekeeping as I pick up working on this again.
[pdclib] / functions / _PDCLIB / fflush.c
index 3d26b400d079611476859eb3d54cbf1eb90bd7d5..e8c99db75122ae33b17230f1c5b26e4932f96604 100644 (file)
@@ -1,27 +1,55 @@
 /* $Id$ */
 
-/* _PDCLIB_fflush( FILE * )
+/* _PDCLIB_flushbuffer( FILE * )
 
    This file is part of the Public Domain C Library (PDCLib).
    Permission is granted to use, modify, and / or redistribute at will.
 */
 
 #include <stdio.h>
+#include <limits.h>
+#include <assert.h>
 
-int _PDCLIB_fflush( struct _PDCLIB_file_t * stream )
+#include <_PDCLIB_glue.h>
+
+_PDCLIB_size_t _PDCLIB_flushbuffer( struct _PDCLIB_file_t * stream, _PDCLIB_size_t written, int retries )
 {
-    if ( fwrite( stream->buffer, stream->bufidx, 1, stream ) == stream->bufidx )
-    {
-        stream->bufidx = 0;
-        return 0;
-    }
-    else
+    _PDCLIB_size_t n = stream->bufidx - written;
+    int count = _PDCLIB_write( stream, stream->buffer + written, ( n <= INT_MAX ? (int)n : INT_MAX ) );
+    written += count; /* if count is -1, we don't need written anyway */
+    switch ( count )
     {
-        stream->status |= _PDCLIB_ERRORFLAG;
-        return EOF;
+        case -1:
+            /* write error */
+            stream->status |= _PDCLIB_ERRORFLAG;
+            /* FIXME: Map host errno to PDCLib errno */
+            return 0;
+        case 0:
+            /* no characters written - retry */
+            if ( retries == _PDCLIB_FLUSH_RETRIES )
+            {
+                /* max. number of retries without characters being written */
+                stream->status |= _PDCLIB_ERRORFLAG;
+                /* FIXME: Set errno */
+                return 0;
+            }
+            _PDCLIB_FLUSH_RETRY_PREP;
+            return _PDCLIB_flushbuffer( stream, written, retries + 1 );
+        default:
+            /* If the following assert fails, we wrote more characters than
+               available in the buffer. (???)
+            */
+            assert( written <= stream->bufidx );
+            if ( written == stream->bufidx ) 
+            {
+                /* write complete */
+                stream->bufidx = 0;
+                return written;
+            }
+            return _PDCLIB_flushbuffer( stream, written, 0 );
     }
 }
-                
+    
 #ifdef TEST
 #include <_PDCLIB_test.h>