]> pd.if.org Git - pdclib/blob - platform/example_cygwin/functions/_PDCLIB/flushbuffer.c
c2ac98d8ef8aac286460ede9a2e4aa8dcf326e7e
[pdclib] / platform / example_cygwin / functions / _PDCLIB / flushbuffer.c
1 /* $Id$ */
2
3 /* _PDCLIB_flushbuffer( struct _PDCLIB_file_t * )
4
5    This file is part of the Public Domain C Library (PDCLib).
6    Permission is granted to use, modify, and / or redistribute at will.
7 */
8
9 /* This is an example implementation of _PDCLIB_flushbuffer() fit for
10    use with POSIX kernels.
11 */
12
13 #include <stdio.h>
14 #include <string.h>
15
16 #ifndef REGTEST
17 #include <_PDCLIB_glue.h>
18
19 #include </usr/include/errno.h>
20
21 typedef long ssize_t;
22 extern ssize_t write( int fd, const void * buf, size_t count );
23
24 /* The number of attempts to complete an output buffer flushing before giving
25  *    up.
26  *    */
27 #define _PDCLIB_IO_RETRIES 1
28
29 /* What the system should do after an I/O operation did not succeed, before   */
30 /* trying again. (Empty by default.)                                          */
31 #define _PDCLIB_IO_RETRY_OP( stream )
32
33 int _PDCLIB_flushbuffer( struct _PDCLIB_file_t * stream )
34 {
35     if ( ! ( stream->status & _PDCLIB_FBIN ) )
36     {
37         /* TODO: Text stream conversion here */
38     }
39     /* No need to handle buffers > INT_MAX, as PDCLib doesn't allow them */
40     _PDCLIB_size_t written = 0;
41     int rc;
42     /* Keep trying to write data until everything is written, an error
43        occurs, or the configured number of retries is exceeded.
44     */
45     for ( unsigned int retries = _PDCLIB_IO_RETRIES; retries > 0; --retries )
46     {
47         rc = (int)write( stream->handle, stream->buffer + written, stream->bufidx - written );
48         if ( rc < 0 )
49         {
50             /* Write error */
51             switch ( errno )
52             {
53                 case EBADF:
54                 case EFAULT:
55                 case EFBIG:
56                 case EINTR:
57                 case EINVAL:
58                 case EIO:
59                 case ENOSPC:
60                 case EPIPE:
61                     _PDCLIB_errno = _PDCLIB_EIO;
62                     break;
63                 default:
64                     _PDCLIB_errno = _PDCLIB_EUNKNOWN;
65                     break;
66             }
67             stream->status |= _PDCLIB_ERRORFLAG;
68             /* Move unwritten remains to begin of buffer. */
69             stream->bufidx -= written;
70             memmove( stream->buffer, stream->buffer + written, stream->bufidx );
71             return EOF;
72         }
73         written += (_PDCLIB_size_t)rc;
74         stream->pos.offset += rc;
75         if ( written == stream->bufidx )
76         {
77             /* Buffer written completely. */
78             stream->bufidx = 0;
79             return 0;
80         }
81     }
82     _PDCLIB_errno = _PDCLIB_ERETRY;
83     stream->status |= _PDCLIB_ERRORFLAG;
84     /* Move unwritten remains to begin of buffer. */
85     stream->bufidx -= written;
86     memmove( stream->buffer, stream->buffer + written, stream->bufidx );
87     return EOF;
88 }
89
90 #endif
91
92
93 #ifdef TEST
94 #include <_PDCLIB_test.h>
95
96 int main( void )
97 {
98     /* Testing covered by ftell.c */
99     return TEST_RESULTS;
100 }
101
102 #endif
103