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