1 // 2 // fputc.cpp 3 // 4 // Copyright (c) Microsoft Corporation. All rights reserved. 5 // 6 // Defines the fputc() family of functions, which write a character to a stream. 7 // 8 #include <corecrt_internal_stdio.h> 9 #include <corecrt_internal_ptd_propagation.h> 10 11 12 extern "C" int __cdecl _fputc_nolock_internal(int const c, FILE* const public_stream, __crt_cached_ptd_host& ptd) 13 { 14 __crt_stdio_stream const stream(public_stream); 15 16 --stream->_cnt; 17 18 // If there is no room for the character in the buffer, flush the buffer and 19 // write the character: 20 if (stream->_cnt < 0) 21 { 22 return __acrt_stdio_flush_and_write_narrow_nolock(c, stream.public_stream(), ptd); 23 } 24 25 // Otherwise, there is sufficient room, so we can write directly to the buffer: 26 char const char_value = static_cast<char>(c); 27 *stream->_ptr++ = char_value; 28 return char_value & 0xff; 29 } 30 31 extern "C" int __cdecl _fputc_nolock(int const c, FILE* const public_stream) 32 { 33 __crt_cached_ptd_host ptd; 34 return _fputc_nolock_internal(c, public_stream, ptd); 35 } 36 37 extern "C" int __cdecl _putc_nolock(int const c, FILE* const stream) 38 { 39 return _fputc_nolock(c, stream); 40 } 41 42 43 44 // Writes a character to a stream. Returns the character on success; returns 45 // EOF on failure. 46 static int __cdecl _fputc_internal(int const c, FILE* const stream, __crt_cached_ptd_host& ptd) 47 { 48 _UCRT_VALIDATE_RETURN(ptd, stream != nullptr, EINVAL, EOF); 49 50 int return_value = 0; 51 52 _lock_file(stream); 53 __try 54 { 55 _UCRT_VALIDATE_STREAM_ANSI_RETURN(ptd, stream, EINVAL, EOF); 56 57 return_value = _fputc_nolock_internal(c, stream, ptd); 58 } 59 __finally 60 { 61 _unlock_file(stream); 62 } 63 __endtry 64 65 return return_value; 66 } 67 68 // Writes a character to a stream. Returns the character on success; returns 69 // EOF on failure. 70 extern "C" int __cdecl fputc(int const c, FILE* const stream) 71 { 72 __crt_cached_ptd_host ptd; 73 return _fputc_internal(c, stream, ptd); 74 } 75 76 77 78 // Writes a character to a stream. See fputc() for details. 79 extern "C" int __cdecl putc(int const c, FILE* const stream) 80 { 81 return fputc(c, stream); 82 } 83 84 85 86 // Writes a character to stdout. See fputc() for details. 87 extern "C" int __cdecl _fputchar(int const c) 88 { 89 return fputc(c, stdout); 90 } 91 92 93 94 // Writes a character to stdout. See fputc() for details. 95 extern "C" int __cdecl putchar(int const c) 96 { 97 return _fputchar(c); 98 } 99