- Add math calls: scalb, fpclass, nextafter, logb, _CI*
[wine] / dlls / crtdll / exit.c
1 /*
2  * CRTDLL exit/abort/atexit functions
3  * 
4  * Copyright 1996,1998 Marcus Meissner
5  * Copyright 1996 Jukka Iivonen
6  * Copyright 1997,2000 Uwe Bonnes
7  * Copyright 2000 Jon Griffiths
8  *
9  * exit functions differ in whether they perform cleanup
10  * and whether they return to the caller (really!).
11  *            return      do
12  *  Name      to caller?  cleanup? 
13  *  _c_exit     Y           N
14  *  _cexit      Y           Y
15  *  _exit       N           N
16  *  exit        N           Y
17  *
18  * Implementation Notes:
19  * Not MT Safe - Adding/Executing exit() functions should be locked
20  * for MT safety.
21  *
22  * FIXME:
23  * Need a better way of printing errors for GUI programs(MsgBox?).
24  * Is there really a difference between onexit/atexit?
25  */
26 #include "crtdll.h"
27 #include <errno.h>
28 #include "process.h"
29
30
31 DEFAULT_DEBUG_CHANNEL(crtdll);
32
33 /* INTERNAL: Table of registered atexit() functions */
34 /* FIXME: This should be dynamically allocated */
35 #define CRTDLL_ATEXIT_TABLE_SIZE 16
36
37 static atexit_function atexit_table[CRTDLL_ATEXIT_TABLE_SIZE];
38 static int atexit_registered = 0; /* Points to free slot */
39
40
41 /* INTERNAL: call atexit functions */
42 void __CRTDLL__call_atexit(VOID);
43 void __CRTDLL__call_atexit(VOID)
44 {
45   /* Last registered gets executed first */
46   while (atexit_registered > 0)
47   {
48     atexit_registered--;
49     TRACE(":call function (%p)\n",atexit_table[atexit_registered]);
50     (*atexit_table[atexit_registered])();
51   }
52 }
53
54
55 /*********************************************************************
56  *                  __dllonexit           (CRTDLL.25)
57  */
58 VOID __cdecl CRTDLL___dllonexit ()
59 {
60     FIXME("stub\n");
61 }
62
63
64 /*********************************************************************
65  *                  _abnormal_termination          (CRTDLL.36)
66  *
67  * Check if execution is processing during an exception.
68  */
69 INT __cdecl CRTDLL__abnormal_termination(VOID)
70 {
71   TRACE("(void)\n");
72   return 0; /* FIME: Can we determine if we are in an exception? */
73 }
74
75
76 /*********************************************************************
77  *                  _amsg_exit     (CRTDLL.040)
78  *
79  * Print an error message and terminate execution. Returns 255 to the
80  * host OS.
81  */
82 VOID __cdecl CRTDLL__amsg_exit(INT err)
83 {
84   CRTDLL_fprintf(CRTDLL_stderr,"\nrun-time error:\nError Code %d\n",err);
85   CRTDLL__exit(255);
86 }
87
88
89 /*********************************************************************
90  *                  _assert     (CRTDLL.041)
91  *
92  * Print an assertion message and call abort(). Really only present 
93  * for win binaries. Winelib programs would typically use libc's
94  * version.
95  */
96 VOID __cdecl CRTDLL__assert(LPVOID str, LPVOID file, UINT line)
97 {
98   CRTDLL_fprintf(CRTDLL_stderr,"Assertion failed: %s, file %s, line %d\n\n",
99                  (char*)str,(char*)file, line);
100   CRTDLL_abort();
101 }
102
103
104 /*********************************************************************
105  *                  _c_exit           (CRTDLL.047)
106  */
107 VOID __cdecl CRTDLL__c_exit(VOID)
108 {
109   FIXME("not calling CRTDLL cleanup\n");
110   /* dont exit, return to caller */
111 }
112
113
114 /*********************************************************************
115  *                  _cexit           (CRTDLL.049)
116  */
117 VOID __cdecl CRTDLL__cexit(VOID)
118 {
119   FIXME("not calling CRTDLL cleanup\n");
120   /* dont exit, return to caller */
121 }
122
123
124 /*********************************************************************
125  *                  _exit           (CRTDLL.087)
126  */
127 VOID __cdecl CRTDLL__exit(LONG ret)
128 {
129   TRACE(":exit code %ld\n",ret);
130   CRTDLL__c_exit();
131   ExitProcess(ret);
132 }
133
134 /*********************************************************************
135  *                  _onexit           (CRTDLL.236)
136  *
137  * Register a function to be called when the process terminates.
138  */
139 atexit_function __cdecl CRTDLL__onexit( atexit_function func)
140 {
141   TRACE("registering function (%p)\n",func);
142   if (func && atexit_registered <= CRTDLL_ATEXIT_TABLE_SIZE - 1)
143   {
144     atexit_table[atexit_registered] = (atexit_function)func;
145     atexit_registered++;
146     return func; /* successful */
147   }
148   ERR(":Too many onexit() functions, or NULL function - not registered!\n");
149   return NULL;
150 }
151
152
153 /*********************************************************************
154  *                  exit          (CRTDLL.359)
155  */
156 void __cdecl CRTDLL_exit(DWORD ret)
157 {
158   TRACE(":exit code %ld\n",ret);
159   __CRTDLL__call_atexit();
160   CRTDLL__cexit();
161   ExitProcess(ret);
162 }
163
164
165 /*********************************************************************
166  *                   abort     (CRTDLL.335)
167  *
168  * Terminate the progam with an abnormal termination message. Returns
169  * 3 to the host OS.
170  */
171 VOID __cdecl CRTDLL_abort()
172 {
173   CRTDLL_fprintf(CRTDLL_stderr,"\nabnormal program termination\n");
174   CRTDLL__exit(3);
175 }
176
177
178 /*********************************************************************
179  *                  atexit           (CRTDLL.345)
180  *
181  * Register a function to be called when the process terminates.
182  */
183 INT __cdecl CRTDLL_atexit( atexit_function func)
184 {
185   return CRTDLL__onexit(func) == func ? 0 : -1;
186 }