source: trunk/src/msvcrt/exit.c

Last change on this file was 10005, checked in by sandervl, 22 years ago

PF: MSVCRT update

File size: 6.8 KB
Line 
1/*
2 * msvcrt.dll exit functions
3 *
4 * Copyright 2000 Jon Griffiths
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20#include "msvcrt.h"
21
22#include "msvcrt/conio.h"
23#include "msvcrt/stdlib.h"
24#include "mtdll.h"
25#include "winuser.h"
26#include <string.h>
27#include "wine/debug.h"
28
29WINE_DEFAULT_DEBUG_CHANNEL(msvcrt);
30
31/* MT */
32#define LOCK_EXIT _mlock(_EXIT_LOCK1)
33#define UNLOCK_EXIT _munlock(_EXIT_LOCK1)
34
35static _onexit_t *MSVCRT_atexit_table = NULL;
36static int MSVCRT_atexit_table_size = 0;
37static int MSVCRT_atexit_registered = 0; /* Points to free slot */
38
39extern int MSVCRT_app_type;
40extern char *MSVCRT__pgmptr;
41
42static LPCSTR szMsgBoxTitle = "Wine C++ Runtime Library";
43
44/* INTERNAL: call atexit functions */
45void __MSVCRT__call_atexit(void)
46{
47 /* Note: should only be called with the exit lock held */
48 TRACE("%d atext functions to call\n", MSVCRT_atexit_registered);
49 /* Last registered gets executed first */
50 while (MSVCRT_atexit_registered > 0)
51 {
52 MSVCRT_atexit_registered--;
53 TRACE("next is %p\n",MSVCRT_atexit_table[MSVCRT_atexit_registered]);
54 if (MSVCRT_atexit_table[MSVCRT_atexit_registered])
55 (*MSVCRT_atexit_table[MSVCRT_atexit_registered])();
56 TRACE("returned\n");
57 }
58}
59
60/*********************************************************************
61 * __dllonexit (MSVCRT.@)
62 */
63_onexit_t __dllonexit(_onexit_t func, _onexit_t **start, _onexit_t **end)
64{
65 _onexit_t *tmp;
66 int len;
67
68 TRACE("(%p,%p,%p)\n", func, start, end);
69
70 if (!start || !*start || !end || !*end)
71 {
72 FIXME("bad table\n");
73 return NULL;
74 }
75
76 len = (*end - *start);
77
78 TRACE("table start %p-%p, %d entries\n", *start, *end, len);
79
80 if (++len <= 0)
81 return NULL;
82
83 tmp = (_onexit_t *)MSVCRT_realloc(*start, len * sizeof(tmp));
84 if (!tmp)
85 return NULL;
86 *start = tmp;
87 *end = tmp + len;
88 tmp[len - 1] = func;
89 TRACE("new table start %p-%p, %d entries\n", *start, *end, len);
90 return func;
91}
92
93/*********************************************************************
94 * _exit (MSVCRT.@)
95 */
96void MSVCRT__exit(int exitcode)
97{
98 TRACE("MSVCRT: _exit (%d)\n", exitcode);
99 ExitProcess(exitcode);
100}
101
102/* Print out an error message with an option to debug */
103static void DoMessageBox(LPCSTR lead, LPCSTR message)
104{
105 MSGBOXPARAMSA msgbox;
106 char text[2048];
107 INT ret;
108
109 _snprintf(text,sizeof(text),"%s\n\nProgram: %s\n%s\n\n"
110 "Press OK to exit the program, or Cancel to start the Wine debugger.\n ",
111 lead, MSVCRT__pgmptr, message);
112
113 msgbox.cbSize = sizeof(msgbox);
114 msgbox.hwndOwner = GetActiveWindow();
115 msgbox.hInstance = 0;
116 msgbox.lpszText = text;
117 msgbox.lpszCaption = szMsgBoxTitle;
118 msgbox.dwStyle = MB_OKCANCEL|MB_ICONERROR;
119 msgbox.lpszIcon = NULL;
120 msgbox.dwContextHelpId = 0;
121 msgbox.lpfnMsgBoxCallback = NULL;
122 msgbox.dwLanguageId = LANG_NEUTRAL;
123
124 ret = MessageBoxIndirectA(&msgbox);
125 if (ret == IDCANCEL)
126 DebugBreak();
127}
128
129/*********************************************************************
130 * _amsg_exit (MSVCRT.@)
131 */
132void MSVCRT__amsg_exit(int errnum)
133{
134 TRACE("MSVCRT: _amsg_exit (%d)\n", errnum);
135 /* FIXME: text for the error number. */
136 if (MSVCRT_app_type == 2)
137 {
138 char text[32];
139 sprintf(text, "Error: R60%d",errnum);
140 DoMessageBox("Runtime error!", text);
141 }
142 else
143 MSVCRT__cprintf("\nruntime error R60%d\n",errnum);
144 MSVCRT__exit(255);
145}
146
147/*********************************************************************
148 * abort (MSVCRT.@)
149 */
150void MSVCRT_abort(void)
151{
152 TRACE("MSVCRT: _abort");
153 if (MSVCRT_app_type == 2)
154 {
155 DoMessageBox("Runtime error!", "abnormal program termination");
156 }
157 else
158 MSVCRT__cputs("\nabnormal program termination\n");
159 MSVCRT__exit(3);
160}
161
162/*********************************************************************
163 * _assert (MSVCRT.@)
164 */
165void MSVCRT__assert(const char* str, const char* file, unsigned int line)
166{
167 TRACE("MSVCRT: _assert (%s,%s,%d)\n",str,file,line);
168 if (MSVCRT_app_type == 2)
169 {
170 char text[2048];
171 _snprintf(text, sizeof(text), "File: %s\nLine: %d\n\nEpression: \"%s\"", file, line, str);
172 DoMessageBox("Assertion failed!", text);
173 }
174 else
175 MSVCRT__cprintf("Assertion failed: %s, file %s, line %d\n\n",str, file, line);
176 MSVCRT__exit(3);
177}
178
179/*********************************************************************
180 * _c_exit (MSVCRT.@)
181 */
182void MSVCRT__c_exit(void)
183{
184 TRACE("MSVCRT: _c_exit (void)\n");
185 /* All cleanup is done on DLL detach; Return to caller */
186}
187
188/*********************************************************************
189 * _cexit (MSVCRT.@)
190 */
191void MSVCRT__cexit(void)
192{
193 TRACE("MSVCRT: _cexit (void)\n");
194 /* All cleanup is done on DLL detach; Return to caller */
195}
196
197/*********************************************************************
198 * _onexit (MSVCRT.@)
199 */
200_onexit_t MSVCRT__onexit(_onexit_t func)
201{
202 TRACE("MSVCRT: _onexit (%p)\n",func);
203
204 if (!func)
205 return NULL;
206
207 LOCK_EXIT;
208 if (MSVCRT_atexit_registered > MSVCRT_atexit_table_size - 1)
209 {
210 _onexit_t *newtable;
211 TRACE("expanding table\n");
212 newtable = MSVCRT_calloc(sizeof(void *),MSVCRT_atexit_table_size + 32);
213 if (!newtable)
214 {
215 TRACE("failed!\n");
216 UNLOCK_EXIT;
217 return NULL;
218 }
219 memcpy (newtable, MSVCRT_atexit_table, MSVCRT_atexit_table_size);
220 MSVCRT_atexit_table_size += 32;
221 if (MSVCRT_atexit_table)
222 MSVCRT_free (MSVCRT_atexit_table);
223 MSVCRT_atexit_table = newtable;
224 }
225 MSVCRT_atexit_table[MSVCRT_atexit_registered] = func;
226 MSVCRT_atexit_registered++;
227 UNLOCK_EXIT;
228 return func;
229}
230
231/*********************************************************************
232 * exit (MSVCRT.@)
233 */
234void MSVCRT_exit(int exitcode)
235{
236 TRACE("MSVCRT: _exit (%d)\n",exitcode);
237 LOCK_EXIT;
238 __MSVCRT__call_atexit();
239 UNLOCK_EXIT;
240 ExitProcess(exitcode);
241}
242
243/*********************************************************************
244 * atexit (MSVCRT.@)
245 */
246int MSVCRT_atexit(void (*func)(void))
247{
248 TRACE("MSVCRT: _atexit (%p)\n", func);
249 return MSVCRT__onexit((_onexit_t)func) == (_onexit_t)func ? 0 : -1;
250}
251
252
253/*********************************************************************
254 * _purecall (MSVCRT.@)
255 */
256void _purecall(void)
257{
258 TRACE("MSVCRT: _purecall (void)\n");
259 MSVCRT__amsg_exit( 25 );
260}
Note: See TracBrowser for help on using the repository browser.