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
;
24 void *MSVCRT_realloc(void *ptr
, unsigned int size
);
26 /* INTERNAL: call atexit functions */
27 void __MSVCRT__call_atexit(void)
29 /* Note: should only be called with the exit lock held */
30 TRACE("%d atext functions to call\n", MSVCRT_atexit_registered
);
31 /* Last registered gets executed first */
32 while (MSVCRT_atexit_registered
> 0)
34 MSVCRT_atexit_registered
--;
35 TRACE("next is %p\n",MSVCRT_atexit_table
[MSVCRT_atexit_registered
]);
36 if (MSVCRT_atexit_table
[MSVCRT_atexit_registered
])
37 (*MSVCRT_atexit_table
[MSVCRT_atexit_registered
])();
42 /*********************************************************************
43 * __dllonexit (MSVCRT.@)
45 _onexit_t
__dllonexit(_onexit_t func
, _onexit_t
**start
, _onexit_t
**end
)
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
= (_onexit_t
*)MSVCRT_realloc(*start
, len
* sizeof(tmp
));
71 TRACE("new table start %p-%p, %d entries\n", *start
, *end
, len
);
75 /*********************************************************************
78 void MSVCRT__exit(int exitcode
)
80 TRACE("(%d)\n", exitcode
);
81 ExitProcess(exitcode
);
84 /*********************************************************************
85 * _amsg_exit (MSVCRT.@)
87 void MSVCRT__amsg_exit(int errnum
)
89 TRACE("(%d)\n", errnum
);
90 /* FIXME: text for the error number. */
91 if (MSVCRT_app_type
== 2)
95 _cprintf("\nruntime error R60%d\n",errnum
);
99 /*********************************************************************
102 void MSVCRT_abort(void)
105 if (MSVCRT_app_type
== 2)
109 _cputs("\nabnormal program termination\n");
113 /*********************************************************************
116 void 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 _cprintf("Assertion failed: %s, file %s, line %d\n\n",str
,file
, line
);
127 /*********************************************************************
130 void MSVCRT__c_exit(void)
133 /* All cleanup is done on DLL detach; Return to caller */
136 /*********************************************************************
139 void MSVCRT__cexit(void)
142 /* All cleanup is done on DLL detach; Return to caller */
145 /*********************************************************************
148 _onexit_t
_onexit(_onexit_t func
)
150 TRACE("(%p)\n",func
);
156 if (MSVCRT_atexit_registered
> MSVCRT_atexit_table_size
- 1)
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 MSVCRT_exit(int exitcode
)
184 TRACE("(%d)\n",exitcode
);
186 __MSVCRT__call_atexit();
188 ExitProcess(exitcode
);
191 /*********************************************************************
194 int MSVCRT_atexit(_onexit_t func
)
196 TRACE("(%p)\n", func
);
197 return _onexit(func
) == func
? 0 : -1;
200 /*********************************************************************
201 * _purecall (MSVCRT.@)
206 MSVCRT__amsg_exit( 25 );