104e0dc4aSTimo Kreuzer //
204e0dc4aSTimo Kreuzer // fputc.cpp
304e0dc4aSTimo Kreuzer //
404e0dc4aSTimo Kreuzer // Copyright (c) Microsoft Corporation. All rights reserved.
504e0dc4aSTimo Kreuzer //
604e0dc4aSTimo Kreuzer // Defines the fputc() family of functions, which write a character to a stream.
704e0dc4aSTimo Kreuzer //
804e0dc4aSTimo Kreuzer #include <corecrt_internal_stdio.h>
904e0dc4aSTimo Kreuzer #include <corecrt_internal_ptd_propagation.h>
1004e0dc4aSTimo Kreuzer
1104e0dc4aSTimo Kreuzer
_fputc_nolock_internal(int const c,FILE * const public_stream,__crt_cached_ptd_host & ptd)1204e0dc4aSTimo Kreuzer extern "C" int __cdecl _fputc_nolock_internal(int const c, FILE* const public_stream, __crt_cached_ptd_host& ptd)
1304e0dc4aSTimo Kreuzer {
1404e0dc4aSTimo Kreuzer __crt_stdio_stream const stream(public_stream);
1504e0dc4aSTimo Kreuzer
1604e0dc4aSTimo Kreuzer --stream->_cnt;
1704e0dc4aSTimo Kreuzer
1804e0dc4aSTimo Kreuzer // If there is no room for the character in the buffer, flush the buffer and
1904e0dc4aSTimo Kreuzer // write the character:
2004e0dc4aSTimo Kreuzer if (stream->_cnt < 0)
2104e0dc4aSTimo Kreuzer {
2204e0dc4aSTimo Kreuzer return __acrt_stdio_flush_and_write_narrow_nolock(c, stream.public_stream(), ptd);
2304e0dc4aSTimo Kreuzer }
2404e0dc4aSTimo Kreuzer
2504e0dc4aSTimo Kreuzer // Otherwise, there is sufficient room, so we can write directly to the buffer:
2604e0dc4aSTimo Kreuzer char const char_value = static_cast<char>(c);
2704e0dc4aSTimo Kreuzer *stream->_ptr++ = char_value;
2804e0dc4aSTimo Kreuzer return char_value & 0xff;
2904e0dc4aSTimo Kreuzer }
3004e0dc4aSTimo Kreuzer
_fputc_nolock(int const c,FILE * const public_stream)3104e0dc4aSTimo Kreuzer extern "C" int __cdecl _fputc_nolock(int const c, FILE* const public_stream)
3204e0dc4aSTimo Kreuzer {
3304e0dc4aSTimo Kreuzer __crt_cached_ptd_host ptd;
3404e0dc4aSTimo Kreuzer return _fputc_nolock_internal(c, public_stream, ptd);
3504e0dc4aSTimo Kreuzer }
3604e0dc4aSTimo Kreuzer
_putc_nolock(int const c,FILE * const stream)3704e0dc4aSTimo Kreuzer extern "C" int __cdecl _putc_nolock(int const c, FILE* const stream)
3804e0dc4aSTimo Kreuzer {
3904e0dc4aSTimo Kreuzer return _fputc_nolock(c, stream);
4004e0dc4aSTimo Kreuzer }
4104e0dc4aSTimo Kreuzer
4204e0dc4aSTimo Kreuzer
4304e0dc4aSTimo Kreuzer
4404e0dc4aSTimo Kreuzer // Writes a character to a stream. Returns the character on success; returns
4504e0dc4aSTimo Kreuzer // EOF on failure.
_fputc_internal(int const c,FILE * const stream,__crt_cached_ptd_host & ptd)4604e0dc4aSTimo Kreuzer static int __cdecl _fputc_internal(int const c, FILE* const stream, __crt_cached_ptd_host& ptd)
4704e0dc4aSTimo Kreuzer {
4804e0dc4aSTimo Kreuzer _UCRT_VALIDATE_RETURN(ptd, stream != nullptr, EINVAL, EOF);
4904e0dc4aSTimo Kreuzer
5004e0dc4aSTimo Kreuzer int return_value = 0;
5104e0dc4aSTimo Kreuzer
5204e0dc4aSTimo Kreuzer _lock_file(stream);
5304e0dc4aSTimo Kreuzer __try
5404e0dc4aSTimo Kreuzer {
5504e0dc4aSTimo Kreuzer _UCRT_VALIDATE_STREAM_ANSI_RETURN(ptd, stream, EINVAL, EOF);
5604e0dc4aSTimo Kreuzer
5704e0dc4aSTimo Kreuzer return_value = _fputc_nolock_internal(c, stream, ptd);
5804e0dc4aSTimo Kreuzer }
5904e0dc4aSTimo Kreuzer __finally
6004e0dc4aSTimo Kreuzer {
6104e0dc4aSTimo Kreuzer _unlock_file(stream);
6204e0dc4aSTimo Kreuzer }
63*e98e9000STimo Kreuzer __endtry
6404e0dc4aSTimo Kreuzer
6504e0dc4aSTimo Kreuzer return return_value;
6604e0dc4aSTimo Kreuzer }
6704e0dc4aSTimo Kreuzer
6804e0dc4aSTimo Kreuzer // Writes a character to a stream. Returns the character on success; returns
6904e0dc4aSTimo Kreuzer // EOF on failure.
fputc(int const c,FILE * const stream)7004e0dc4aSTimo Kreuzer extern "C" int __cdecl fputc(int const c, FILE* const stream)
7104e0dc4aSTimo Kreuzer {
7204e0dc4aSTimo Kreuzer __crt_cached_ptd_host ptd;
7304e0dc4aSTimo Kreuzer return _fputc_internal(c, stream, ptd);
7404e0dc4aSTimo Kreuzer }
7504e0dc4aSTimo Kreuzer
7604e0dc4aSTimo Kreuzer
7704e0dc4aSTimo Kreuzer
7804e0dc4aSTimo Kreuzer // Writes a character to a stream. See fputc() for details.
putc(int const c,FILE * const stream)7904e0dc4aSTimo Kreuzer extern "C" int __cdecl putc(int const c, FILE* const stream)
8004e0dc4aSTimo Kreuzer {
8104e0dc4aSTimo Kreuzer return fputc(c, stream);
8204e0dc4aSTimo Kreuzer }
8304e0dc4aSTimo Kreuzer
8404e0dc4aSTimo Kreuzer
8504e0dc4aSTimo Kreuzer
8604e0dc4aSTimo Kreuzer // Writes a character to stdout. See fputc() for details.
_fputchar(int const c)8704e0dc4aSTimo Kreuzer extern "C" int __cdecl _fputchar(int const c)
8804e0dc4aSTimo Kreuzer {
8904e0dc4aSTimo Kreuzer return fputc(c, stdout);
9004e0dc4aSTimo Kreuzer }
9104e0dc4aSTimo Kreuzer
9204e0dc4aSTimo Kreuzer
9304e0dc4aSTimo Kreuzer
9404e0dc4aSTimo Kreuzer // Writes a character to stdout. See fputc() for details.
putchar(int const c)9504e0dc4aSTimo Kreuzer extern "C" int __cdecl putchar(int const c)
9604e0dc4aSTimo Kreuzer {
9704e0dc4aSTimo Kreuzer return _fputchar(c);
9804e0dc4aSTimo Kreuzer }
99