xref: /reactos/sdk/lib/ucrt/lowio/txtmode.cpp (revision fe93a3f9)
1 //
2 // txtmode.cpp
3 //
4 //      Copyright (c) Microsoft Corporation. All rights reserved.
5 //
6 // Defines the global _fmode variable and sets the global file mode to text.
7 // This is the default behavior.
8 //
9 #include <corecrt_internal.h>
10 #include <fcntl.h>
11 #include <stdlib.h>
12 
13 // Clients of the static CRT can choose to access _fmode directly as a global variable; they do so as if it was declared as an int.
14 // Because state separation is disabled in the static CRT, the dual_state_global<int> has the same representation as an int, so this is okay, if a bit messy.
15 __crt_state_management::dual_state_global<int> _fmode;  // This is automatically initialized to zero by the compiler
16 
17 extern "C" int* __cdecl __p__fmode()
18 {
19     _BEGIN_SECURE_CRT_DEPRECATION_DISABLE
20     return &_fmode.value();
21     _END_SECURE_CRT_DEPRECATION_DISABLE
22 }
23 
24 // Initializer for fmode global correction.
25 _CRT_LINKER_FORCE_INCLUDE(__acrt_fmode_initializer);
26 
27 extern "C" int __cdecl __acrt_initialize_fmode()
28 {
29     // The initial mode for _fmode is initialized during pre_c_initializer() in vcstartup, so that it can be overridden with a linkopt.
30     // The default value is provided by _get_startup_file_mode(), but this value is not used to initialize both _fmode states.
31     // (ex: if exe is Prog-Mode, OS-Mode _fmode is uninitialized, if exe is OS-Mode, Prog-Mode _fmode is uninitialized)
32 
33     // To fix this, we adjust zero-value _fmode to _O_TEXT, since that is the default.
34     // Only the exe can use the linkopt, so the state that is not being initialized could not have requested _O_BINARY.
35 
36     int * const fmode_states = _fmode.dangerous_get_state_array();
37     for (unsigned int i = 0; i != __crt_state_management::state_index_count; ++i)
38     {
39         int& fmode_state = fmode_states[i];
40         if (fmode_state == 0)
41         {
42             fmode_state = _O_TEXT;
43         }
44     }
45 
46     return 0;
47 }
48