2 * msvcrt.dll exit functions
4 * Copyright 2000 Jon Griffiths
8 DEFAULT_DEBUG_CHANNEL(msvcrt);
11 extern CRITICAL_SECTION MSVCRT_exit_cs;
12 #define LOCK_EXIT EnterCriticalSection(&MSVCRT_exit_cs)
13 #define UNLOCK_EXIT LeaveCriticalSection(&MSVCRT_exit_cs)
15 typedef void (__cdecl *MSVCRT_atexit_func)(void);
17 static MSVCRT_atexit_func *MSVCRT_atexit_table = NULL;
18 static int MSVCRT_atexit_table_size = 0;
19 static int MSVCRT_atexit_registered = 0; /* Points to free slot */
21 extern int MSVCRT_app_type;
22 void *__cdecl MSVCRT_realloc(void *ptr, unsigned int size);
24 /* INTERNAL: call atexit functions */
25 void __MSVCRT__call_atexit(void)
27 /* Note: should only be called with the exit lock held */
28 TRACE("%d atext functions to call\n", MSVCRT_atexit_registered);
29 /* Last registered gets executed first */
30 while (MSVCRT_atexit_registered > 0)
32 MSVCRT_atexit_registered--;
33 TRACE("next is %p\n",MSVCRT_atexit_table[MSVCRT_atexit_registered]);
34 if (MSVCRT_atexit_table[MSVCRT_atexit_registered])
35 (*MSVCRT_atexit_table[MSVCRT_atexit_registered])();
40 /*********************************************************************
41 * __dllonexit (MSVCRT.@)
43 MSVCRT_atexit_func __cdecl MSVCRT___dllonexit(MSVCRT_atexit_func func,
44 MSVCRT_atexit_func **start,
45 MSVCRT_atexit_func **end)
47 MSVCRT_atexit_func *tmp;
50 TRACE("(%p,%p,%p)\n", func, start, end);
52 if (!start || !*start || !end || !*end)
58 len = (*end - *start);
60 TRACE("table start %p-%p, %d entries\n", *start, *end, len);
65 tmp = (MSVCRT_atexit_func *)MSVCRT_realloc(*start, len * sizeof(tmp));
71 TRACE("new table start %p-%p, %d entries\n", *start, *end, len);
75 /*********************************************************************
78 void __cdecl MSVCRT__exit(int exitcode)
80 TRACE("(%d)\n", exitcode);
81 ExitProcess(exitcode);
84 /*********************************************************************
85 * _amsg_exit (MSVCRT.@)
87 void __cdecl MSVCRT__amsg_exit(int errnum)
89 TRACE("(%d)\n", errnum);
90 /* FIXME: text for the error number. */
91 if (MSVCRT_app_type == 2)
95 MSVCRT__cprintf("\nruntime error R60%d\n",errnum);
99 /*********************************************************************
102 void __cdecl MSVCRT_abort(void)
105 if (MSVCRT_app_type == 2)
109 MSVCRT__cputs("\nabnormal program termination\n");
113 /*********************************************************************
116 void __cdecl MSVCRT__assert(const char* str, const char* file, unsigned int line)
118 TRACE("(%s,%s,%d)\n",str,file,line);
119 if (MSVCRT_app_type == 2)
123 MSVCRT__cprintf("Assertion failed: %s, file %s, line %d\n\n",str,file, line);
127 /*********************************************************************
130 void __cdecl MSVCRT__c_exit(void)
133 /* All cleanup is done on DLL detach; Return to caller */
136 /*********************************************************************
139 void __cdecl MSVCRT__cexit(void)
142 /* All cleanup is done on DLL detach; Return to caller */
145 /*********************************************************************
148 MSVCRT_atexit_func __cdecl MSVCRT__onexit(MSVCRT_atexit_func func)
150 TRACE("(%p)\n",func);
156 if (MSVCRT_atexit_registered > MSVCRT_atexit_table_size - 1)
158 MSVCRT_atexit_func *newtable;
159 TRACE("expanding table\n");
160 newtable = MSVCRT_calloc(sizeof(void *),MSVCRT_atexit_table_size + 32);
167 memcpy (newtable, MSVCRT_atexit_table, MSVCRT_atexit_table_size);
168 MSVCRT_atexit_table_size += 32;
169 if (MSVCRT_atexit_table)
170 MSVCRT_free (MSVCRT_atexit_table);
171 MSVCRT_atexit_table = newtable;
173 MSVCRT_atexit_table[MSVCRT_atexit_registered] = func;
174 MSVCRT_atexit_registered++;
179 /*********************************************************************
182 void __cdecl MSVCRT_exit(int exitcode)
184 TRACE("(%d)\n",exitcode);
186 __MSVCRT__call_atexit();
188 ExitProcess(exitcode);
191 /*********************************************************************
194 int __cdecl MSVCRT_atexit(MSVCRT_atexit_func func)
196 TRACE("(%p)\n", func);
197 return MSVCRT__onexit(func) == func ? 0 : -1;
200 /*********************************************************************
201 * _purecall (MSVCRT.@)
203 void __cdecl MSVCRT__purecall(void)
206 MSVCRT__amsg_exit( 25 );