xref: /reactos/sdk/lib/crt/stdio/_flsbuf.c (revision c2c66aff)
1*c2c66affSColin Finck /*
2*c2c66affSColin Finck  * COPYRIGHT:       GNU GPL, see COPYING in the top level directory
3*c2c66affSColin Finck  * PROJECT:         ReactOS crt library
4*c2c66affSColin Finck  * FILE:            lib/sdk/crt/stdio/_flsbuf.c
5*c2c66affSColin Finck  * PURPOSE:         Implementation of _flsbuf / _flswbuf
6*c2c66affSColin Finck  * PROGRAMMER:      Timo Kreuzer
7*c2c66affSColin Finck  */
8*c2c66affSColin Finck 
9*c2c66affSColin Finck #include <precomp.h>
10*c2c66affSColin Finck 
11*c2c66affSColin Finck BOOL __cdecl msvcrt_alloc_buffer(FILE *stream);
12*c2c66affSColin Finck 
13*c2c66affSColin Finck int __cdecl
_flsbuf(int ch,FILE * stream)14*c2c66affSColin Finck _flsbuf(int ch, FILE *stream)
15*c2c66affSColin Finck {
16*c2c66affSColin Finck     int count, written;
17*c2c66affSColin Finck 
18*c2c66affSColin Finck     /* Check if the stream supports flushing */
19*c2c66affSColin Finck     if ((stream->_flag & _IOSTRG) || !(stream->_flag & (_IORW|_IOWRT)))
20*c2c66affSColin Finck     {
21*c2c66affSColin Finck         stream->_flag |= _IOERR;
22*c2c66affSColin Finck         return EOF;
23*c2c66affSColin Finck     }
24*c2c66affSColin Finck 
25*c2c66affSColin Finck     /* Always reset _cnt */
26*c2c66affSColin Finck     stream->_cnt = 0;
27*c2c66affSColin Finck 
28*c2c66affSColin Finck     /* Check if this was a read buffer */
29*c2c66affSColin Finck     if (stream->_flag & _IOREAD)
30*c2c66affSColin Finck     {
31*c2c66affSColin Finck         /* Must be at the end of the file */
32*c2c66affSColin Finck         if (!(stream->_flag & _IOEOF))
33*c2c66affSColin Finck         {
34*c2c66affSColin Finck             stream->_flag |= _IOERR;
35*c2c66affSColin Finck             return EOF;
36*c2c66affSColin Finck         }
37*c2c66affSColin Finck 
38*c2c66affSColin Finck         /* Reset buffer */
39*c2c66affSColin Finck         stream->_ptr = stream->_base;
40*c2c66affSColin Finck     }
41*c2c66affSColin Finck 
42*c2c66affSColin Finck     /* Fixup flags */
43*c2c66affSColin Finck     stream->_flag &= ~(_IOREAD|_IOEOF);
44*c2c66affSColin Finck     stream->_flag |= _IOWRT;
45*c2c66affSColin Finck 
46*c2c66affSColin Finck     /* Check if should get a buffer */
47*c2c66affSColin Finck     if (!(stream->_flag & _IONBF) && stream != stdout && stream != stderr)
48*c2c66affSColin Finck     {
49*c2c66affSColin Finck         /* If we have no buffer, try to allocate one */
50*c2c66affSColin Finck         if (!stream->_base) msvcrt_alloc_buffer(stream);
51*c2c66affSColin Finck     }
52*c2c66affSColin Finck 
53*c2c66affSColin Finck     /* Check if we can use a buffer now */
54*c2c66affSColin Finck     if (stream->_base && !(stream->_flag & _IONBF))
55*c2c66affSColin Finck     {
56*c2c66affSColin Finck         /* We can, check if there is something to write */
57*c2c66affSColin Finck         count = (int)(stream->_ptr - stream->_base);
58*c2c66affSColin Finck         if (count > 0)
59*c2c66affSColin Finck             written = _write(stream->_file, stream->_base, count);
60*c2c66affSColin Finck         else
61*c2c66affSColin Finck             written = 0;
62*c2c66affSColin Finck 
63*c2c66affSColin Finck         /* Reset buffer and put the char into it */
64*c2c66affSColin Finck         stream->_ptr = stream->_base + sizeof(TCHAR);
65*c2c66affSColin Finck         stream->_cnt = stream->_bufsiz - sizeof(TCHAR);
66*c2c66affSColin Finck         *(TCHAR*)stream->_base = ch;
67*c2c66affSColin Finck     }
68*c2c66affSColin Finck     else
69*c2c66affSColin Finck     {
70*c2c66affSColin Finck         /* There is no buffer, write the char directly */
71*c2c66affSColin Finck         count = sizeof(TCHAR);
72*c2c66affSColin Finck         written = _write(stream->_file, &ch, sizeof(TCHAR));
73*c2c66affSColin Finck     }
74*c2c66affSColin Finck 
75*c2c66affSColin Finck     /* Check for failure */
76*c2c66affSColin Finck     if (written != count)
77*c2c66affSColin Finck     {
78*c2c66affSColin Finck         stream->_flag |= _IOERR;
79*c2c66affSColin Finck         return EOF;
80*c2c66affSColin Finck     }
81*c2c66affSColin Finck 
82*c2c66affSColin Finck     return ch & (sizeof(TCHAR) > sizeof(char) ? 0xffff : 0xff);
83*c2c66affSColin Finck }
84