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