Reactos
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.
19template <typename Character>
20static 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
63extern "C" FILE* __cdecl _fdopen(int const fh, char const* const mode)
64{
65 return common_fdopen(fh, mode);
66}
67
68extern "C" FILE* __cdecl _wfdopen(int const fh, wchar_t const* const mode)
69{
70 return common_fdopen(fh, mode);
71}