source: trunk/src/msvcrt/exit.c@ 9633

Last change on this file since 9633 was 9633, checked in by sandervl, 23 years ago

PF: Msvcrt Wine port with GCC

File size: 5.4 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
26#include "wine/debug.h"
27
28WINE_DEFAULT_DEBUG_CHANNEL(msvcrt);
29
30/* MT */
31#define LOCK_EXIT _mlock(_EXIT_LOCK1)
32#define UNLOCK_EXIT _munlock(_EXIT_LOCK1)
33
34static _onexit_t *MSVCRT_atexit_table = NULL;
35static int MSVCRT_atexit_table_size = 0;
36static int MSVCRT_atexit_registered = 0; /* Points to free slot */
37
38extern int MSVCRT_app_type;
39
40/* INTERNAL: call atexit functions */
41void __MSVCRT__call_atexit(void)
42{
43 /* Note: should only be called with the exit lock held */
44 TRACE("%d atext functions to call\n", MSVCRT_atexit_registered);
45 /* Last registered gets executed first */
46 while (MSVCRT_atexit_registered > 0)
47 {
48 MSVCRT_atexit_registered--;
49 TRACE("next is %p\n",MSVCRT_atexit_table[MSVCRT_atexit_registered]);
50 if (MSVCRT_atexit_table[MSVCRT_atexit_registered])
51 (*MSVCRT_atexit_table[MSVCRT_atexit_registered])();
52 TRACE("returned\n");
53 }
54}
55
56/*********************************************************************
57 * __dllonexit (MSVCRT.@)
58 */
59_onexit_t __dllonexit(_onexit_t func, _onexit_t **start, _onexit_t **end)
60{
61 _onexit_t *tmp;
62 int len;
63
64 TRACE("(%p,%p,%p)\n", func, start, end);
65
66 if (!start || !*start || !end || !*end)
67 {
68 FIXME("bad table\n");
69 return NULL;
70 }
71
72 len = (*end - *start);
73
74 TRACE("table start %p-%p, %d entries\n", *start, *end, len);
75
76 if (++len <= 0)
77 return NULL;
78
79 tmp = (_onexit_t *)MSVCRT_realloc(*start, len * sizeof(tmp));
80 if (!tmp)
81 return NULL;
82 *start = tmp;
83 *end = tmp + len;
84 tmp[len - 1] = func;
85 TRACE("new table start %p-%p, %d entries\n", *start, *end, len);
86 return func;
87}
88
89/*********************************************************************
90 * _exit (MSVCRT.@)
91 */
92void MSVCRT__exit(int exitcode)
93{
94 TRACE("(%d)\n", exitcode);
95 ExitProcess(exitcode);
96}
97
98/*********************************************************************
99 * _amsg_exit (MSVCRT.@)
100 */
101void MSVCRT__amsg_exit(int errnum)
102{
103 TRACE("(%d)\n", errnum);
104 /* FIXME: text for the error number. */
105 if (MSVCRT_app_type == 2)
106 {
107 /* FIXME: MsgBox */
108 }
109 _cprintf("\nruntime error R60%d\n",errnum);
110 MSVCRT__exit(255);
111}
112
113/*********************************************************************
114 * abort (MSVCRT.@)
115 */
116void MSVCRT_abort(void)
117{
118 TRACE("(void)\n");
119 if (MSVCRT_app_type == 2)
120 {
121 /* FIXME: MsgBox */
122 }
123 _cputs("\nabnormal program termination\n");
124 MSVCRT__exit(3);
125}
126
127/*********************************************************************
128 * _assert (MSVCRT.@)
129 */
130void MSVCRT__assert(const char* str, const char* file, unsigned int line)
131{
132 TRACE("(%s,%s,%d)\n",str,file,line);
133 if (MSVCRT_app_type == 2)
134 {
135 /* FIXME: MsgBox */
136 }
137 _cprintf("Assertion failed: %s, file %s, line %d\n\n",str,file, line);
138 MSVCRT_abort();
139}
140
141/*********************************************************************
142 * _c_exit (MSVCRT.@)
143 */
144void MSVCRT__c_exit(void)
145{
146 TRACE("(void)\n");
147 /* All cleanup is done on DLL detach; Return to caller */
148}
149
150/*********************************************************************
151 * _cexit (MSVCRT.@)
152 */
153void MSVCRT__cexit(void)
154{
155 TRACE("(void)\n");
156 /* All cleanup is done on DLL detach; Return to caller */
157}
158
159/*********************************************************************
160 * _onexit (MSVCRT.@)
161 */
162_onexit_t _onexit(_onexit_t func)
163{
164 TRACE("(%p)\n",func);
165
166 if (!func)
167 return NULL;
168
169 LOCK_EXIT;
170 if (MSVCRT_atexit_registered > MSVCRT_atexit_table_size - 1)
171 {
172 _onexit_t *newtable;
173 TRACE("expanding table\n");
174 newtable = MSVCRT_calloc(sizeof(void *),MSVCRT_atexit_table_size + 32);
175 if (!newtable)
176 {
177 TRACE("failed!\n");
178 UNLOCK_EXIT;
179 return NULL;
180 }
181 memcpy (newtable, MSVCRT_atexit_table, MSVCRT_atexit_table_size);
182 MSVCRT_atexit_table_size += 32;
183 if (MSVCRT_atexit_table)
184 MSVCRT_free (MSVCRT_atexit_table);
185 MSVCRT_atexit_table = newtable;
186 }
187 MSVCRT_atexit_table[MSVCRT_atexit_registered] = func;
188 MSVCRT_atexit_registered++;
189 UNLOCK_EXIT;
190 return func;
191}
192
193/*********************************************************************
194 * exit (MSVCRT.@)
195 */
196void MSVCRT_exit(int exitcode)
197{
198 TRACE("(%d)\n",exitcode);
199 LOCK_EXIT;
200 __MSVCRT__call_atexit();
201 UNLOCK_EXIT;
202 ExitProcess(exitcode);
203}
204
205/*********************************************************************
206 * atexit (MSVCRT.@)
207 */
208int MSVCRT_atexit(void (*func)(void))
209{
210 TRACE("(%p)\n", func);
211 return _onexit((_onexit_t)func) == (_onexit_t)func ? 0 : -1;
212}
213
214
215/*********************************************************************
216 * _purecall (MSVCRT.@)
217 */
218void _purecall(void)
219{
220 TRACE("(void)\n");
221 MSVCRT__amsg_exit( 25 );
222}
Note: See TracBrowser for help on using the repository browser.