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