Reactos
1//
2// setmode.cpp
3//
4// Copyright (c) Microsoft Corporation. All rights reserved.
5//
6// Defines _setmode(), which sets the translation mode for a file, and
7// _set_fmode() and _get_fmode(), which control the global default translation
8// mode.
9//
10#include <corecrt_internal_lowio.h>
11#include <stdlib.h>
12
13
14
15// Sets the file translation mode. This changes the file mode to text or binary,
16// depending on the mode argument. This affects whether reads and writes on the
17// file translate between CRLF and LF. Returns the old file translation mode on
18// success, or -1 on failure.
19extern "C" int __cdecl _setmode(int const fh, int const mode)
20{
21 _VALIDATE_RETURN(mode == _O_TEXT ||
22 mode == _O_BINARY ||
23 mode == _O_WTEXT ||
24 mode == _O_U8TEXT ||
25 mode == _O_U16TEXT,
26 EINVAL, -1);
27
28 _CHECK_FH_RETURN(fh, EBADF, -1);
29 _VALIDATE_RETURN((fh >= 0 && (unsigned)fh < (unsigned)_nhandle), EBADF, -1);
30 _VALIDATE_RETURN((_osfile(fh) & FOPEN), EBADF, -1);
31
32 __acrt_lowio_lock_fh(fh);
33 int result = -1;
34 __try
35 {
36 if ((_osfile(fh) & FOPEN) == 0)
37 {
38 errno = EBADF;
39 _ASSERTE(("Invalid file descriptor. File possibly closed by a different thread",0));
40 __leave;
41 }
42
43 result = _setmode_nolock(fh, mode);
44 }
45 __finally
46 {
47 __acrt_lowio_unlock_fh(fh);
48 }
49 __endtry
50 return result;
51}
52
53
54
55extern "C" int __cdecl _setmode_nolock(int const fh, int const mode)
56{
57 int const old_mode = _osfile(fh) & FTEXT;
58 __crt_lowio_text_mode const old_textmode = _textmode(fh);
59
60 switch (mode)
61 {
62 case _O_BINARY:
63 _osfile(fh) &= ~FTEXT;
64 break;
65
66 case _O_TEXT:
67 _osfile(fh) |= FTEXT;
68 _textmode(fh) = __crt_lowio_text_mode::ansi;
69 break;
70
71 case _O_U8TEXT:
72 _osfile(fh) |= FTEXT;
73 _textmode(fh) = __crt_lowio_text_mode::utf8;
74 break;
75
76 case _O_U16TEXT:
77 case _O_WTEXT:
78 _osfile(fh) |= FTEXT;
79 _textmode(fh) = __crt_lowio_text_mode::utf16le;
80 break;
81 }
82
83 if (old_mode == 0)
84 return _O_BINARY;
85
86 if (old_textmode == __crt_lowio_text_mode::ansi)
87 {
88 return _O_TEXT;
89 }
90 else if (old_textmode == __crt_lowio_text_mode::utf8)
91 {
92 return _O_U8TEXT;
93 }
94
95 return _O_WTEXT;
96}
97
98
99
100extern "C" errno_t __cdecl _set_fmode(int const mode)
101{
102 _VALIDATE_RETURN_ERRCODE(mode == _O_TEXT || mode == _O_BINARY || mode == _O_WTEXT, EINVAL);
103
104 _BEGIN_SECURE_CRT_DEPRECATION_DISABLE
105 _InterlockedExchange(reinterpret_cast<long*>(&_fmode.value()), mode);
106 _END_SECURE_CRT_DEPRECATION_DISABLE
107
108 return 0;
109}
110
111
112
113extern "C" errno_t __cdecl _get_fmode(int* const pMode)
114{
115 _VALIDATE_RETURN_ERRCODE(pMode != nullptr, EINVAL);
116
117 _BEGIN_SECURE_CRT_DEPRECATION_DISABLE
118 *pMode = __crt_interlocked_read(&_fmode.value());
119 _END_SECURE_CRT_DEPRECATION_DISABLE
120
121 return 0;
122}