ReactOS 0.4.16-dev-1078-g21d3e29
_flsbuf.cpp File Reference
Include dependency graph for _flsbuf.cpp:

Go to the source code of this file.

Functions

static bool __cdecl stream_is_at_end_of_file_nolock (__crt_stdio_stream const stream) throw ()
 
template<typename Character >
static bool __cdecl write_buffer_nolock (Character const c, __crt_stdio_stream const stream, __crt_cached_ptd_host &ptd) throw ()
 
template<typename Character >
static int __cdecl common_flush_and_write_nolock (int const c, __crt_stdio_stream const stream, __crt_cached_ptd_host &ptd) throw ()
 
int __cdecl __acrt_stdio_flush_and_write_narrow_nolock (int const c, FILE *const stream, __crt_cached_ptd_host &ptd)
 
int __cdecl __acrt_stdio_flush_and_write_wide_nolock (int const c, FILE *const stream, __crt_cached_ptd_host &ptd)
 

Function Documentation

◆ __acrt_stdio_flush_and_write_narrow_nolock()

int __cdecl __acrt_stdio_flush_and_write_narrow_nolock ( int const  c,
FILE *const  stream,
__crt_cached_ptd_host &  ptd 
)

Definition at line 195 of file _flsbuf.cpp.

200{
201 return common_flush_and_write_nolock<char>(c, __crt_stdio_stream(stream), ptd);
202}
_In_ size_t const _In_ int _In_ bool const _In_ unsigned const _In_ __acrt_rounding_mode const _Inout_ __crt_cached_ptd_host & ptd
Definition: cvt.cpp:355
const GLubyte * c
Definition: glext.h:8905
Definition: parse.h:23

Referenced by __DEFINE_CPP_OVERLOAD_STANDARD_FUNC_0_0(), _fputc_nolock_internal(), and _fwrite_nolock_internal().

◆ __acrt_stdio_flush_and_write_wide_nolock()

int __cdecl __acrt_stdio_flush_and_write_wide_nolock ( int const  c,
FILE *const  stream,
__crt_cached_ptd_host &  ptd 
)

Definition at line 206 of file _flsbuf.cpp.

211{
212 return common_flush_and_write_nolock<wchar_t>(c, __crt_stdio_stream(stream), ptd);
213}

Referenced by __DEFINE_CPP_OVERLOAD_STANDARD_FUNC_0_0(), and fputwc_binary_nolock().

◆ common_flush_and_write_nolock()

template<typename Character >
static int __cdecl common_flush_and_write_nolock ( int const  c,
__crt_stdio_stream const  stream,
__crt_cached_ptd_host &  ptd 
)
throw (
)
static

Definition at line 113 of file _flsbuf.cpp.

118{
119 typedef __acrt_stdio_char_traits<Character> stdio_traits;
120
121 unsigned const character_mask = (1 << (CHAR_BIT * sizeof(Character))) - 1;
122
123 _ASSERTE(stream.valid());
124
125 int const fh = _fileno(stream.public_stream());
126
127 if (!stream.has_any_of(_IOWRITE | _IOUPDATE))
128 {
129 ptd.get_errno().set(EBADF);
130 stream.set_flags(_IOERROR);
131 return stdio_traits::eof;
132 }
133 else if (stream.is_string_backed())
134 {
135 ptd.get_errno().set(ERANGE);
136 stream.set_flags(_IOERROR);
137 return stdio_traits::eof;
138 }
139
140 // Check that _IOREAD is not set or, if it is, then so is _IOEOF. Note
141 // that _IOREAD and IOEOF both being set implies switching from read to
142 // write at end-of-file, which is allowed by ANSI. Note that resetting
143 // the _cnt and _ptr fields amounts to doing an fflush() on the stream
144 // in this case. Note also that the _cnt field has to be reset to 0 for
145 // the error path as well (i.e., _IOREAD set but _IOEOF not set) as
146 // well as the non-error path.
147
148 if (stream.has_any_of(_IOREAD))
149 {
150 bool const switch_to_write_mode = stream_is_at_end_of_file_nolock(stream);
151 stream->_cnt = 0; // in either case, flush buffer
152
153 if (switch_to_write_mode)
154 {
155 stream->_ptr = stream->_base;
156 stream.unset_flags(_IOREAD);
157 }
158 else
159 {
160 stream.set_flags(_IOERROR);
161 return stdio_traits::eof;
162 }
163 }
164
165 stream.set_flags(_IOWRITE);
166 stream.unset_flags(_IOEOF);
167
168 stream->_cnt = 0;
169
170 // Get a buffer for this stream, if one is necessary:
171 if (!stream.has_any_buffer())
172 {
173 // If the stream uses temporary buffering, we do not set up a single character buffer;
174 // this is so that later temporary buffering will not be thwarted by
175 // the _IONBF flag being set. (See _stbuf() and _ftbuf() for more
176 //information on stdout and stderr buffering.)
177 if (!__acrt_should_use_temporary_buffer(stream.public_stream()))
178 {
180 }
181 }
182
183 // Write the character; return (W)EOF if it fails:
184 if (!write_buffer_nolock(static_cast<Character>(c & character_mask), stream, ptd))
185 {
186 stream.set_flags(_IOERROR);
187 return stdio_traits::eof;
188 }
189
190 return c & character_mask;
191}
static bool __cdecl write_buffer_nolock(Character const c, __crt_stdio_stream const stream, __crt_cached_ptd_host &ptd)
Definition: _flsbuf.cpp:58
static bool __cdecl stream_is_at_end_of_file_nolock(__crt_stdio_stream const stream)
Definition: _flsbuf.cpp:11
void __cdecl __acrt_stdio_allocate_buffer_nolock(FILE *const public_stream)
Definition: _getbuf.cpp:16
bool __acrt_should_use_temporary_buffer(FILE *const stream)
Definition: _sftbuf.cpp:34
#define ERANGE
Definition: acclib.h:92
#define EBADF
Definition: acclib.h:82
#define _ASSERTE(expr)
Definition: crtdbg.h:114
#define CHAR_BIT
Definition: urlcache.c:62
_Check_return_ _CRTIMP int __cdecl _fileno(_In_ FILE *_File)
#define _IOEOF
Definition: stdio.h:132
#define _IOREAD
Definition: stdio.h:124

◆ stream_is_at_end_of_file_nolock()

static bool __cdecl stream_is_at_end_of_file_nolock ( __crt_stdio_stream const  stream)
throw (
)
static

Definition at line 11 of file _flsbuf.cpp.

14{
15 if (stream.has_any_of(_IOEOF))
16 {
17 return true;
18 }
19
20 // If there is any data in the buffer, then we are not at the end of the file.
21 if (stream.has_big_buffer() && (stream->_ptr == stream->_base))
22 {
23 return false;
24 }
25
26 HANDLE const os_handle = reinterpret_cast<HANDLE>(_get_osfhandle(stream.lowio_handle()));
27
28 // If we fail at querying for the file size, proceed as though we cannot
29 // gather that information. For example, this will fail with pipes.
30 if (os_handle == INVALID_HANDLE_VALUE)
31 {
32 return false;
33 }
34
35 // Both SetFilePointerEx and GetFileSizeEx are valid ways to determine the
36 // length of a file. We can use that equivalence to check for end-of-file.
37
38 // This is a racy condition to check - a write or read from another process
39 // could interfere with the size reported from GetFileSizeEx.
40 // In that case, the write function looking to switch from read to write mode
41 // will fail in the usual manner when the write was not possible.
42 LARGE_INTEGER current_position;
43 if (!SetFilePointerEx(os_handle, {}, &current_position, FILE_CURRENT))
44 {
45 return false;
46 }
47
48 LARGE_INTEGER eof_position;
49 if (!GetFileSizeEx(os_handle, &eof_position))
50 {
51 return false;
52 }
53
54 return current_position.QuadPart == eof_position.QuadPart;
55}
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
#define GetFileSizeEx
Definition: compat.h:757
BOOL WINAPI SetFilePointerEx(HANDLE hFile, LARGE_INTEGER liDistanceToMove, PLARGE_INTEGER lpNewFilePointer, DWORD dwMoveMethod)
Definition: fileinfo.c:177
_CRTIMP intptr_t __cdecl _get_osfhandle(_In_ int _FileHandle)
LONGLONG QuadPart
Definition: typedefs.h:114
#define FILE_CURRENT
Definition: winbase.h:114

Referenced by common_flush_and_write_nolock().

◆ write_buffer_nolock()

template<typename Character >
static bool __cdecl write_buffer_nolock ( Character const  c,
__crt_stdio_stream const  stream,
__crt_cached_ptd_host &  ptd 
)
throw (
)
static

Definition at line 58 of file _flsbuf.cpp.

63{
64 typedef __acrt_stdio_char_traits<Character> stdio_traits;
65
66 int const fh = _fileno(stream.public_stream());
67
68 // If the stream is buffered, write the buffer if there are characters to
69 // be written, then push the character 'c' into the buffer:
70 if (stream.has_big_buffer())
71 {
72 _ASSERTE(("inconsistent IOB fields", stream->_ptr - stream->_base >= 0));
73
74 int const chars_to_write = static_cast<int>(stream->_ptr - stream->_base);
75 stream->_ptr = stream->_base + sizeof(Character);
76 stream->_cnt = stream->_bufsiz - static_cast<int>(sizeof(Character));
77
78 int chars_written = 0;
79 if (chars_to_write > 0)
80 {
81 chars_written = _write_internal(fh, stream->_base, chars_to_write, ptd);
82 }
83 else
84 {
85 if (_osfile_safe(fh) & FAPPEND)
86 {
87 if (_lseeki64(fh, 0, SEEK_END) == -1)
88 {
89 stream.set_flags(_IOERROR);
90 return stdio_traits::eof;
91 }
92 }
93 }
94
95 *reinterpret_cast<Character*>(stream->_base) = c;
96 return chars_written == chars_to_write;
97 }
98 // Otherwise, perform a single character write (if we get here, either
99 // _IONBF is set or there is no buffering):
100 else
101 {
102 return _write_internal(fh, reinterpret_cast<char const*>(&c), sizeof(c), ptd) == sizeof(Character);
103 }
104}
#define SEEK_END
Definition: cabinet.c:29
int __cdecl _write_internal(_In_ int _FileHandle, _In_reads_bytes_(_MaxCharCount) void const *_Buf, _In_ unsigned int _MaxCharCount, _Inout_ __crt_cached_ptd_host &_Ptd)
#define _osfile_safe(i)
Definition: internal.h:78
__int64 CDECL _lseeki64(int fd, __int64 offset, int whence)
Definition: file.c:1138
#define const
Definition: zconf.h:233

Referenced by common_flush_and_write_nolock().