xref: /reactos/sdk/lib/ucrt/lowio/setmode.cpp (revision e3e520d1)
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.
19 extern "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 
55 extern "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 
100 extern "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 
113 extern "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 }
123