2 * msvcrt.dll exit functions
4 * Copyright 2000 Jon Griffiths
8 #include "msvcrt/conio.h"
9 #include "msvcrt/stdlib.h"
12 #include "wine/debug.h"
14 WINE_DEFAULT_DEBUG_CHANNEL(msvcrt);
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])();
43 /*********************************************************************
44 * __dllonexit (MSVCRT.@)
46 _onexit_t __dllonexit(_onexit_t func, _onexit_t **start, _onexit_t **end)
51 TRACE("(%p,%p,%p)\n", func, start, end);
53 if (!start || !*start || !end || !*end)
59 len = (*end - *start);
61 TRACE("table start %p-%p, %d entries\n", *start, *end, len);
66 tmp = (_onexit_t *)MSVCRT_realloc(*start, len * sizeof(tmp));
72 TRACE("new table start %p-%p, %d entries\n", *start, *end, len);
76 /*********************************************************************
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)
96 _cprintf("\nruntime error R60%d\n",errnum);
100 /*********************************************************************
103 void MSVCRT_abort(void)
106 if (MSVCRT_app_type == 2)
110 _cputs("\nabnormal program termination\n");
114 /*********************************************************************
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)
124 _cprintf("Assertion failed: %s, file %s, line %d\n\n",str,file, line);
128 /*********************************************************************
131 void MSVCRT__c_exit(void)
134 /* All cleanup is done on DLL detach; Return to caller */
137 /*********************************************************************
140 void MSVCRT__cexit(void)
143 /* All cleanup is done on DLL detach; Return to caller */
146 /*********************************************************************
149 _onexit_t _onexit(_onexit_t func)
151 TRACE("(%p)\n",func);
157 if (MSVCRT_atexit_registered > MSVCRT_atexit_table_size - 1)
160 TRACE("expanding table\n");
161 newtable = MSVCRT_calloc(sizeof(void *),MSVCRT_atexit_table_size + 32);
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++;
180 /*********************************************************************
183 void MSVCRT_exit(int exitcode)
185 TRACE("(%d)\n",exitcode);
187 __MSVCRT__call_atexit();
189 ExitProcess(exitcode);
192 /*********************************************************************
195 int MSVCRT_atexit(_onexit_t func)
197 TRACE("(%p)\n", func);
198 return _onexit(func) == func ? 0 : -1;
201 /*********************************************************************
202 * _purecall (MSVCRT.@)
207 MSVCRT__amsg_exit( 25 );