Make FIXMEs more grep-able.
[wine/multimedia.git] / dlls / msvcrt / exit.c
blob274035a6fc8d8e118f236d9154980ae5d1655e9f
1 /*
2 * msvcrt.dll exit functions
4 * Copyright 2000 Jon Griffiths
5 */
6 #include "msvcrt.h"
8 #include "msvcrt/conio.h"
9 #include "msvcrt/stdlib.h"
12 #include "wine/debug.h"
14 WINE_DEFAULT_DEBUG_CHANNEL(msvcrt);
16 /* MT */
17 extern CRITICAL_SECTION MSVCRT_exit_cs;
18 #define LOCK_EXIT EnterCriticalSection(&MSVCRT_exit_cs)
19 #define UNLOCK_EXIT LeaveCriticalSection(&MSVCRT_exit_cs)
21 static _onexit_t *MSVCRT_atexit_table = NULL;
22 static int MSVCRT_atexit_table_size = 0;
23 static int MSVCRT_atexit_registered = 0; /* Points to free slot */
25 extern int MSVCRT_app_type;
27 /* INTERNAL: call atexit functions */
28 void __MSVCRT__call_atexit(void)
30 /* Note: should only be called with the exit lock held */
31 TRACE("%d atext functions to call\n", MSVCRT_atexit_registered);
32 /* Last registered gets executed first */
33 while (MSVCRT_atexit_registered > 0)
35 MSVCRT_atexit_registered--;
36 TRACE("next is %p\n",MSVCRT_atexit_table[MSVCRT_atexit_registered]);
37 if (MSVCRT_atexit_table[MSVCRT_atexit_registered])
38 (*MSVCRT_atexit_table[MSVCRT_atexit_registered])();
39 TRACE("returned\n");
43 /*********************************************************************
44 * __dllonexit (MSVCRT.@)
46 _onexit_t __dllonexit(_onexit_t func, _onexit_t **start, _onexit_t **end)
48 _onexit_t *tmp;
49 int len;
51 TRACE("(%p,%p,%p)\n", func, start, end);
53 if (!start || !*start || !end || !*end)
55 FIXME("bad table\n");
56 return NULL;
59 len = (*end - *start);
61 TRACE("table start %p-%p, %d entries\n", *start, *end, len);
63 if (++len <= 0)
64 return NULL;
66 tmp = (_onexit_t *)MSVCRT_realloc(*start, len * sizeof(tmp));
67 if (!tmp)
68 return NULL;
69 *start = tmp;
70 *end = tmp + len;
71 tmp[len - 1] = func;
72 TRACE("new table start %p-%p, %d entries\n", *start, *end, len);
73 return func;
76 /*********************************************************************
77 * _exit (MSVCRT.@)
79 void MSVCRT__exit(int exitcode)
81 TRACE("(%d)\n", exitcode);
82 ExitProcess(exitcode);
85 /*********************************************************************
86 * _amsg_exit (MSVCRT.@)
88 void MSVCRT__amsg_exit(int errnum)
90 TRACE("(%d)\n", errnum);
91 /* FIXME: text for the error number. */
92 if (MSVCRT_app_type == 2)
94 /* FIXME: MsgBox */
96 _cprintf("\nruntime error R60%d\n",errnum);
97 MSVCRT__exit(255);
100 /*********************************************************************
101 * abort (MSVCRT.@)
103 void MSVCRT_abort(void)
105 TRACE("(void)\n");
106 if (MSVCRT_app_type == 2)
108 /* FIXME: MsgBox */
110 _cputs("\nabnormal program termination\n");
111 MSVCRT__exit(3);
114 /*********************************************************************
115 * _assert (MSVCRT.@)
117 void MSVCRT__assert(const char* str, const char* file, unsigned int line)
119 TRACE("(%s,%s,%d)\n",str,file,line);
120 if (MSVCRT_app_type == 2)
122 /* FIXME: MsgBox */
124 _cprintf("Assertion failed: %s, file %s, line %d\n\n",str,file, line);
125 MSVCRT_abort();
128 /*********************************************************************
129 * _c_exit (MSVCRT.@)
131 void MSVCRT__c_exit(void)
133 TRACE("(void)\n");
134 /* All cleanup is done on DLL detach; Return to caller */
137 /*********************************************************************
138 * _cexit (MSVCRT.@)
140 void MSVCRT__cexit(void)
142 TRACE("(void)\n");
143 /* All cleanup is done on DLL detach; Return to caller */
146 /*********************************************************************
147 * _onexit (MSVCRT.@)
149 _onexit_t _onexit(_onexit_t func)
151 TRACE("(%p)\n",func);
153 if (!func)
154 return NULL;
156 LOCK_EXIT;
157 if (MSVCRT_atexit_registered > MSVCRT_atexit_table_size - 1)
159 _onexit_t *newtable;
160 TRACE("expanding table\n");
161 newtable = MSVCRT_calloc(sizeof(void *),MSVCRT_atexit_table_size + 32);
162 if (!newtable)
164 TRACE("failed!\n");
165 UNLOCK_EXIT;
166 return NULL;
168 memcpy (newtable, MSVCRT_atexit_table, MSVCRT_atexit_table_size);
169 MSVCRT_atexit_table_size += 32;
170 if (MSVCRT_atexit_table)
171 MSVCRT_free (MSVCRT_atexit_table);
172 MSVCRT_atexit_table = newtable;
174 MSVCRT_atexit_table[MSVCRT_atexit_registered] = func;
175 MSVCRT_atexit_registered++;
176 UNLOCK_EXIT;
177 return func;
180 /*********************************************************************
181 * exit (MSVCRT.@)
183 void MSVCRT_exit(int exitcode)
185 TRACE("(%d)\n",exitcode);
186 LOCK_EXIT;
187 __MSVCRT__call_atexit();
188 UNLOCK_EXIT;
189 ExitProcess(exitcode);
192 /*********************************************************************
193 * atexit (MSVCRT.@)
195 int MSVCRT_atexit(_onexit_t func)
197 TRACE("(%p)\n", func);
198 return _onexit(func) == func ? 0 : -1;
201 /*********************************************************************
202 * _purecall (MSVCRT.@)
204 void _purecall(void)
206 TRACE("(void)\n");
207 MSVCRT__amsg_exit( 25 );