xref: /reactos/sdk/lib/ucrt/stdio/fdopen.cpp (revision 53d808d2)
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