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 );