2 * msvcrt.dll exit functions
4 * Copyright 2000 Jon Griffiths
8 #include "msvcrt/conio.h"
9 #include "msvcrt/stdlib.h"
12 DEFAULT_DEBUG_CHANNEL(msvcrt);
15 extern CRITICAL_SECTION MSVCRT_exit_cs;
16 #define LOCK_EXIT EnterCriticalSection(&MSVCRT_exit_cs)
17 #define UNLOCK_EXIT LeaveCriticalSection(&MSVCRT_exit_cs)
19 static _onexit_t *MSVCRT_atexit_table = NULL;
20 static int MSVCRT_atexit_table_size = 0;
21 static int MSVCRT_atexit_registered = 0; /* Points to free slot */
23 extern int MSVCRT_app_type;
25 /* INTERNAL: call atexit functions */
26 void __MSVCRT__call_atexit(void)
28 /* Note: should only be called with the exit lock held */
29 TRACE("%d atext functions to call\n", MSVCRT_atexit_registered);
30 /* Last registered gets executed first */
31 while (MSVCRT_atexit_registered > 0)
33 MSVCRT_atexit_registered--;
34 TRACE("next is %p\n",MSVCRT_atexit_table[MSVCRT_atexit_registered]);
35 if (MSVCRT_atexit_table[MSVCRT_atexit_registered])
36 (*MSVCRT_atexit_table[MSVCRT_atexit_registered])();
41 /*********************************************************************
42 * __dllonexit (MSVCRT.@)
44 _onexit_t __dllonexit(_onexit_t func, _onexit_t **start, _onexit_t **end)
49 TRACE("(%p,%p,%p)\n", func, start, end);
51 if (!start || !*start || !end || !*end)
57 len = (*end - *start);
59 TRACE("table start %p-%p, %d entries\n", *start, *end, len);
64 tmp = (_onexit_t *)MSVCRT_realloc(*start, len * sizeof(tmp));
70 TRACE("new table start %p-%p, %d entries\n", *start, *end, len);
74 /*********************************************************************
77 void MSVCRT__exit(int exitcode)
79 TRACE("(%d)\n", exitcode);
80 ExitProcess(exitcode);
83 /*********************************************************************
84 * _amsg_exit (MSVCRT.@)
86 void MSVCRT__amsg_exit(int errnum)
88 TRACE("(%d)\n", errnum);
89 /* FIXME: text for the error number. */
90 if (MSVCRT_app_type == 2)
94 _cprintf("\nruntime error R60%d\n",errnum);
98 /*********************************************************************
101 void MSVCRT_abort(void)
104 if (MSVCRT_app_type == 2)
108 _cputs("\nabnormal program termination\n");
112 /*********************************************************************
115 void MSVCRT__assert(const char* str, const char* file, unsigned int line)
117 TRACE("(%s,%s,%d)\n",str,file,line);
118 if (MSVCRT_app_type == 2)
122 _cprintf("Assertion failed: %s, file %s, line %d\n\n",str,file, line);
126 /*********************************************************************
129 void MSVCRT__c_exit(void)
132 /* All cleanup is done on DLL detach; Return to caller */
135 /*********************************************************************
138 void MSVCRT__cexit(void)
141 /* All cleanup is done on DLL detach; Return to caller */
144 /*********************************************************************
147 _onexit_t _onexit(_onexit_t func)
149 TRACE("(%p)\n",func);
155 if (MSVCRT_atexit_registered > MSVCRT_atexit_table_size - 1)
158 TRACE("expanding table\n");
159 newtable = MSVCRT_calloc(sizeof(void *),MSVCRT_atexit_table_size + 32);
166 memcpy (newtable, MSVCRT_atexit_table, MSVCRT_atexit_table_size);
167 MSVCRT_atexit_table_size += 32;
168 if (MSVCRT_atexit_table)
169 MSVCRT_free (MSVCRT_atexit_table);
170 MSVCRT_atexit_table = newtable;
172 MSVCRT_atexit_table[MSVCRT_atexit_registered] = func;
173 MSVCRT_atexit_registered++;
178 /*********************************************************************
181 void MSVCRT_exit(int exitcode)
183 TRACE("(%d)\n",exitcode);
185 __MSVCRT__call_atexit();
187 ExitProcess(exitcode);
190 /*********************************************************************
193 int MSVCRT_atexit(_onexit_t func)
195 TRACE("(%p)\n", func);
196 return _onexit(func) == func ? 0 : -1;
199 /*********************************************************************
200 * _purecall (MSVCRT.@)
205 MSVCRT__amsg_exit( 25 );