]> pd.if.org Git - pdclib/blob - platform/win32/crt0.c
win32: crt0: initialize locale TSS
[pdclib] / platform / win32 / crt0.c
1 #include <string.h>\r
2 #include <stdlib.h>\r
3 #include <stdio.h>\r
4 #include <signal.h>\r
5 #include <threads.h>\r
6 #include <wchar.h> // Watcom bug: winnt.h assumes string.h defines wchar_t\r
7 #include <windows.h>\r
8 #include <_PDCLIB_io.h>\r
9 #include <_PDCLIB_locale.h>\r
10 \r
11 static char ** argvToAnsi( wchar_t ** wargv, int argc )\r
12 {\r
13     char ** argv = malloc( sizeof( *argv ) * argc );\r
14     for ( int i = 0; i != argc; ++i ) {\r
15         int sz = WideCharToMultiByte( CP_ACP, WC_COMPOSITECHECK | WC_SEPCHARS,\r
16                                       wargv[i], -1, NULL, 0, NULL, NULL );\r
17         if(!(argv[i] = malloc(sz))) {\r
18             fputs("Error in C runtime initialization: "\r
19                   "unable to allocate buffer for argument", stderr);\r
20             abort();\r
21         }\r
22 \r
23         int rv = WideCharToMultiByte( CP_ACP, WC_COMPOSITECHECK | WC_SEPCHARS,\r
24                                       wargv[i], -1, argv[i], sz, NULL, NULL );\r
25 \r
26         if(rv != sz) {\r
27             fputs("Error in C runtime initialization: "\r
28                   "size mismatch during character set conversion", stderr);\r
29             abort();\r
30         }\r
31     }\r
32     return argv;\r
33 }\r
34 \r
35 static int        argc;\r
36 static wchar_t *  cl;\r
37 static wchar_t ** wargv;\r
38 static char    ** argv;\r
39 \r
40 static void freeArgs( void )\r
41 {\r
42     for(int i = 0; i != argc; i++) {\r
43         free( argv[i] );\r
44     }\r
45     free( argv );\r
46     LocalFree( wargv );\r
47 }\r
48 \r
49 extern void (*_PDCLIB_sigfpe)( int );\r
50 extern void (*_PDCLIB_sigill)( int );\r
51 extern void (*_PDCLIB_sigsegv)( int );\r
52 \r
53 static LPTOP_LEVEL_EXCEPTION_FILTER oldFilter;\r
54 static LONG CALLBACK sehExceptionFilter( EXCEPTION_POINTERS * exInfo )\r
55 {\r
56     int sig;\r
57     void (*handler)( int );\r
58 \r
59     switch( exInfo->ExceptionRecord->ExceptionCode ) {\r
60         case EXCEPTION_ACCESS_VIOLATION:\r
61         case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:\r
62         case EXCEPTION_DATATYPE_MISALIGNMENT:\r
63         case EXCEPTION_GUARD_PAGE:\r
64         case EXCEPTION_IN_PAGE_ERROR:\r
65         case EXCEPTION_STACK_OVERFLOW:\r
66             sig = SIGSEGV;\r
67             handler = _PDCLIB_sigsegv;\r
68             break;\r
69 \r
70         case EXCEPTION_ILLEGAL_INSTRUCTION:\r
71         case EXCEPTION_PRIV_INSTRUCTION:\r
72             sig = SIGILL;\r
73             handler = _PDCLIB_sigill;\r
74             break;\r
75 \r
76         case EXCEPTION_INT_DIVIDE_BY_ZERO:\r
77         case EXCEPTION_INT_OVERFLOW:\r
78         case EXCEPTION_FLT_DENORMAL_OPERAND:\r
79         case EXCEPTION_FLT_DIVIDE_BY_ZERO:\r
80         case EXCEPTION_FLT_INEXACT_RESULT:\r
81         case EXCEPTION_FLT_INVALID_OPERATION:\r
82         case EXCEPTION_FLT_OVERFLOW:\r
83         case EXCEPTION_FLT_STACK_CHECK:\r
84         case EXCEPTION_FLT_UNDERFLOW:\r
85             sig = SIGFPE;\r
86             handler = _PDCLIB_sigfpe;\r
87             break;\r
88 \r
89         default:\r
90             return oldFilter ? oldFilter( exInfo ) : EXCEPTION_EXECUTE_HANDLER;\r
91     }\r
92 \r
93     if(handler == SIG_DFL) {\r
94         return EXCEPTION_EXECUTE_HANDLER;\r
95     } else if(handler == SIG_IGN) {\r
96         return EXCEPTION_CONTINUE_EXECUTION;\r
97     } else {\r
98         handler( sig );\r
99         return EXCEPTION_CONTINUE_EXECUTION;\r
100     }\r
101 }\r
102 \r
103 extern int main( int argc, char ** argv, char ** envp );\r
104 \r
105 void __cdecl mainCRTStartup( void );\r
106 \r
107 void __cdecl mainCRTStartup( void ) \r
108 {\r
109     stdin->handle.pointer  = GetStdHandle(STD_INPUT_HANDLE);\r
110     stdout->handle.pointer = GetStdHandle(STD_OUTPUT_HANDLE);\r
111     stderr->handle.pointer = GetStdHandle(STD_ERROR_HANDLE);\r
112 \r
113     oldFilter = SetUnhandledExceptionFilter( sehExceptionFilter );\r
114 \r
115     cl    = GetCommandLineW();\r
116     wargv = CommandLineToArgvW(cl, &argc);\r
117     argv  = argvToAnsi(wargv, argc);\r
118 \r
119     if(tss_create(&_PDCLIB_locale_tss, (tss_dtor_t) freelocale) \r
120             != thrd_success) {\r
121         fputs( "Error during C runtime initialization: "\r
122                "Unable to allocate locale TLS", stderr );\r
123         exit( EXIT_FAILURE );\r
124     }\r
125 \r
126     if(        mtx_init(&stdin->lock, mtx_recursive) != thrd_success \r
127             || mtx_init(&stdout->lock, mtx_recursive) != thrd_success\r
128             || mtx_init(&stderr->lock, mtx_recursive) != thrd_success ) {\r
129         fputs( "Error during C runtime initialization: "\r
130             "Unable to allocate stdio mutex", stderr );\r
131         exit( EXIT_FAILURE );\r
132     }\r
133 \r
134     atexit(freeArgs);\r
135 \r
136     int exitStatus = main(argc, argv, NULL);\r
137 \r
138     exit(exitStatus);\r
139 }