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