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