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