1 // 2 // fdopen.cpp 3 // 4 // Copyright (c) Microsoft Corporation. All rights reserved. 5 // 6 // Defines functions that open a stdio stream over an existing lowio file handle. 7 // 8 #include <corecrt_internal_stdio.h> 9 10 11 12 // Opens a lowio file handle as a stdio stream. This associates a stream with 13 // the specified file handle, thus allowing buffering and use with the stdio 14 // functions. The mode must be specified and must be compatible with the mode 15 // with which the file was opened in lowio. 16 // 17 // Returns the new FILE* associated with the file handle on success; returns 18 // nullptr on failure. 19 template <typename Character> 20 static FILE* __cdecl common_fdopen( 21 int const fh, 22 Character const* const mode 23 ) throw() 24 { 25 _VALIDATE_RETURN(mode != nullptr, EINVAL, nullptr); 26 27 _CHECK_FH_RETURN(fh, EBADF, nullptr); 28 _VALIDATE_RETURN(fh >= 0 && (unsigned)fh < (unsigned)_nhandle, EBADF, nullptr); 29 _VALIDATE_RETURN(_osfile(fh) & FOPEN, EBADF, nullptr); 30 31 __acrt_stdio_stream_mode const parsed_mode = __acrt_stdio_parse_mode(mode); 32 if (!parsed_mode._success) 33 return nullptr; 34 35 __crt_stdio_stream stream = __acrt_stdio_allocate_stream(); 36 if (!stream.valid()) 37 { 38 errno = EMFILE; 39 return nullptr; 40 } 41 42 __try 43 { 44 // Ensure that streams get flushed during pre-termination: 45 #ifndef CRTDLL 46 ++_cflush; 47 #endif 48 49 stream.set_flags(parsed_mode._stdio_mode); 50 stream->_file = fh; 51 } 52 __finally 53 { 54 stream.unlock(); 55 } 56 __endtry 57 58 return stream.public_stream(); 59 } 60 61 62 63 extern "C" FILE* __cdecl _fdopen(int const fh, char const* const mode) 64 { 65 return common_fdopen(fh, mode); 66 } 67 68 extern "C" FILE* __cdecl _wfdopen(int const fh, wchar_t const* const mode) 69 { 70 return common_fdopen(fh, mode); 71 } 72