• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * This file has no copyright assigned and is placed in the Public Domain.
3  * This file is part of the mingw-w64 runtime package.
4  * No warranty is given; refer to the file DISCLAIMER.PD within this package.
5  */
6 
7 #ifdef __GNUC__
8 #pragma GCC diagnostic push
9 #pragma GCC diagnostic ignored "-Winline"
10 #endif
11 
12 #undef __MSVCRT_VERSION__
13 #define _UCRT
14 
15 #define __getmainargs crtimp___getmainargs
16 #define __wgetmainargs crtimp___wgetmainargs
17 #define _amsg_exit crtimp__amsg_exit
18 #define _get_output_format crtimp__get_output_format
19 
20 #include <internal.h>
21 #include <sect_attribs.h>
22 #include <stdio.h>
23 #include <time.h>
24 
25 #undef __getmainargs
26 #undef __wgetmainargs
27 #undef _amsg_exit
28 #undef _get_output_format
29 
30 
31 
32 // Declarations of non-static functions implemented within this file (that aren't
33 // declared in any of the included headers, and that isn't mapped away with a define
34 // to get rid of the _CRTIMP in headers).
35 int __cdecl __getmainargs(int * _Argc, char *** _Argv, char ***_Env, int _DoWildCard, _startupinfo *_StartInfo);
36 int __cdecl __wgetmainargs(int * _Argc, wchar_t *** _Argv, wchar_t ***_Env, int _DoWildCard, _startupinfo *_StartInfo);
37 void __cdecl _amsg_exit(int ret);
38 unsigned int __cdecl _get_output_format(void);
39 
40 int __cdecl __ms_fwprintf(FILE *, const wchar_t *, ...);
41 
42 // Declarations of functions from ucrtbase.dll that we use below
43 _CRTIMP int* __cdecl __p___argc(void);
44 _CRTIMP char*** __cdecl __p___argv(void);
45 _CRTIMP wchar_t*** __cdecl __p___wargv(void);
46 _CRTIMP char*** __cdecl __p__environ(void);
47 _CRTIMP wchar_t*** __cdecl __p__wenviron(void);
48 
49 _CRTIMP int __cdecl _crt_atexit(_onexit_t func);
50 
51 _CRTIMP int __cdecl _initialize_narrow_environment(void);
52 _CRTIMP int __cdecl _initialize_wide_environment(void);
53 _CRTIMP int __cdecl _configure_narrow_argv(int mode);
54 _CRTIMP int __cdecl _configure_wide_argv(int mode);
55 
56 // Declared in new.h, but only visible to C++
57 _CRTIMP int __cdecl _set_new_mode(int _NewMode);
58 
59 
60 // Wrappers with legacy msvcrt.dll style API, based on the new ucrtbase.dll functions.
__getmainargs(int * _Argc,char *** _Argv,char *** _Env,int _DoWildCard,_startupinfo * _StartInfo)61 int __cdecl __getmainargs(int * _Argc, char *** _Argv, char ***_Env, int _DoWildCard, _startupinfo *_StartInfo)
62 {
63   _initialize_narrow_environment();
64   _configure_narrow_argv(_DoWildCard ? 2 : 1);
65   *_Argc = *__p___argc();
66   *_Argv = *__p___argv();
67   *_Env = *__p__environ();
68   if (_StartInfo)
69     _set_new_mode(_StartInfo->newmode);
70   return 0;
71 }
72 
__wgetmainargs(int * _Argc,wchar_t *** _Argv,wchar_t *** _Env,int _DoWildCard,_startupinfo * _StartInfo)73 int __cdecl __wgetmainargs(int * _Argc, wchar_t *** _Argv, wchar_t ***_Env, int _DoWildCard, _startupinfo *_StartInfo)
74 {
75   _initialize_wide_environment();
76   _configure_wide_argv(_DoWildCard ? 2 : 1);
77   *_Argc = *__p___argc();
78   *_Argv = *__p___wargv();
79   *_Env = *__p__wenviron();
80   if (_StartInfo)
81     _set_new_mode(_StartInfo->newmode);
82   return 0;
83 }
84 
_onexit(_onexit_t func)85 _onexit_t __cdecl _onexit(_onexit_t func)
86 {
87   return _crt_atexit(func) == 0 ? func : NULL;
88 }
89 
90 _onexit_t __cdecl (*__MINGW_IMP_SYMBOL(_onexit))(_onexit_t func) = _onexit;
91 
_amsg_exit(int ret)92 void __cdecl _amsg_exit(int ret) {
93   fprintf(stderr, "runtime error %d\n", ret);
94 }
95 
_get_output_format(void)96 unsigned int __cdecl _get_output_format(void)
97 {
98   return 0;
99 }
100 
101 static char ** local__initenv;
102 static wchar_t ** local__winitenv;
103 char *** __MINGW_IMP_SYMBOL(__initenv) = &local__initenv;
104 wchar_t *** __MINGW_IMP_SYMBOL(__winitenv) = &local__winitenv;
105 
106 
107 // These are required to provide the unrepfixed data symbols "timezone"
108 // and "tzname"; we can't remap "timezone" via a define due to clashes
109 // with e.g. "struct timezone".
110 typedef void __cdecl (*_tzset_func)(void);
111 extern _tzset_func __MINGW_IMP_SYMBOL(_tzset);
112 
113 // Default initial values until _tzset has been called; these are the same
114 // as the initial values in msvcrt/ucrtbase.
115 static char initial_tzname0[] = "PST";
116 static char initial_tzname1[] = "PDT";
117 static char *initial_tznames[] = { initial_tzname0, initial_tzname1 };
118 static long initial_timezone = 28800;
119 static int initial_daylight = 1;
120 char** __MINGW_IMP_SYMBOL(tzname) = initial_tznames;
121 long * __MINGW_IMP_SYMBOL(timezone) = &initial_timezone;
122 int * __MINGW_IMP_SYMBOL(daylight) = &initial_daylight;
123 
_tzset(void)124 void __cdecl _tzset(void)
125 {
126   __MINGW_IMP_SYMBOL(_tzset)();
127   // Redirect the __imp_ pointers to the actual data provided by the UCRT.
128   // From this point, the exposed values should stay in sync.
129   __MINGW_IMP_SYMBOL(tzname) = _tzname;
130   __MINGW_IMP_SYMBOL(timezone) = __timezone();
131   __MINGW_IMP_SYMBOL(daylight) = __daylight();
132 }
133 
tzset(void)134 void __cdecl tzset(void)
135 {
136   _tzset();
137 }
138 
139 // This is called for wchar cases with __USE_MINGW_ANSI_STDIO enabled (where the
140 // char case just uses fputc).
__ms_fwprintf(FILE * file,const wchar_t * fmt,...)141 int __cdecl __ms_fwprintf(FILE *file, const wchar_t *fmt, ...)
142 {
143   va_list ap;
144   int ret;
145   va_start(ap, fmt);
146   ret = __stdio_common_vfwprintf(UCRTBASE_PRINTF_LEGACY_WIDE_SPECIFIERS, file, fmt, NULL, ap);
147   va_end(ap);
148   return ret;
149 }
150 
151 // Dummy/unused __imp_ wrappers, to make GNU ld not autoexport these symbols.
152 int __cdecl (*__MINGW_IMP_SYMBOL(__getmainargs))(int *, char ***, char ***, int, _startupinfo *) = __getmainargs;
153 int __cdecl (*__MINGW_IMP_SYMBOL(__wgetmainargs))(int *, wchar_t ***, wchar_t ***, int, _startupinfo *) = __wgetmainargs;
154 void __cdecl (*__MINGW_IMP_SYMBOL(_amsg_exit))(int) = _amsg_exit;
155 unsigned int __cdecl (*__MINGW_IMP_SYMBOL(_get_output_format))(void) = _get_output_format;
156 void __cdecl (*__MINGW_IMP_SYMBOL(tzset))(void) = tzset;
157 int __cdecl (*__MINGW_IMP_SYMBOL(__ms_fwprintf))(FILE *, const wchar_t *, ...) = __ms_fwprintf;
158 #ifdef __GNUC__
159 #pragma GCC diagnostic pop
160 #endif
161