Fixed crtdll compile problem regarding fpos_t in glibc2.2.
[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
29
30 DEFAULT_DEBUG_CHANNEL(crtdll);
31
32 /* INTERNAL: Table of registered atexit() functions */
33 /* FIXME: This should be dynamically allocated */
34 #define CRTDLL_ATEXIT_TABLE_SIZE 16
35
36 static atexit_function atexit_table[CRTDLL_ATEXIT_TABLE_SIZE];
37 static int atexit_registered = 0; /* Points to free slot */
38
39
40 /* INTERNAL: call atexit functions */
41 void __CRTDLL__call_atexit(VOID);
42 void __CRTDLL__call_atexit(VOID)
43 {
44   /* Last registered gets executed first */
45   while (atexit_registered > 0)
46   {
47     atexit_registered--;
48     TRACE(":call function (%p)\n",atexit_table[atexit_registered]);
49     (*atexit_table[atexit_registered])();
50   }
51 }
52
53
54 /*********************************************************************
55  *                  __dllonexit           (CRTDLL.25)
56  */
57 VOID __cdecl CRTDLL___dllonexit ()
58 {
59     FIXME("stub\n");
60 }
61
62
63 /*********************************************************************
64  *                  _abnormal_termination          (CRTDLL.36)
65  *
66  * Check if execution is processing during an exception.
67  */
68 INT __cdecl CRTDLL__abnormal_termination(VOID)
69 {
70   TRACE("(void)\n");
71   return 0; /* FIME: Can we determine if we are in an exception? */
72 }
73
74
75 /*********************************************************************
76  *                  _amsg_exit     (CRTDLL.040)
77  *
78  * Print an error message and terminate execution. Returns 255 to the
79  * host OS.
80  */
81 VOID __cdecl CRTDLL__amsg_exit(INT err)
82 {
83   CRTDLL_fprintf(CRTDLL_stderr,"\nrun-time error:\nError Code %d\n",err);
84   CRTDLL__exit(255);
85 }
86
87
88 /*********************************************************************
89  *                  _assert     (CRTDLL.041)
90  *
91  * Print an assertion message and call abort(). Really only present 
92  * for win binaries. Winelib programs would typically use libc's
93  * version.
94  */
95 VOID __cdecl CRTDLL__assert(LPVOID str, LPVOID file, UINT line)
96 {
97   CRTDLL_fprintf(CRTDLL_stderr,"Assertion failed: %s, file %s, line %d\n\n",
98                  (char*)str,(char*)file, line);
99   CRTDLL_abort();
100 }
101
102
103 /*********************************************************************
104  *                  _c_exit           (CRTDLL.047)
105  */
106 VOID __cdecl CRTDLL__c_exit(VOID)
107 {
108   /* All cleanup is done on DLL detach; Return to caller */
109 }
110
111
112 /*********************************************************************
113  *                  _cexit           (CRTDLL.049)
114  */
115 VOID __cdecl CRTDLL__cexit(VOID)
116 {
117   /* All cleanup is done on DLL detach; Return to caller */
118 }
119
120
121 /*********************************************************************
122  *                  _exit           (CRTDLL.087)
123  */
124 VOID __cdecl CRTDLL__exit(LONG ret)
125 {
126   TRACE(":exit code %ld\n",ret);
127   CRTDLL__c_exit();
128   ExitProcess(ret);
129 }
130
131 /*********************************************************************
132  *                  _onexit           (CRTDLL.236)
133  *
134  * Register a function to be called when the process terminates.
135  */
136 atexit_function __cdecl CRTDLL__onexit( atexit_function func)
137 {
138   TRACE("registering function (%p)\n",func);
139   if (func && atexit_registered <= CRTDLL_ATEXIT_TABLE_SIZE - 1)
140   {
141     atexit_table[atexit_registered] = (atexit_function)func;
142     atexit_registered++;
143     return func; /* successful */
144   }
145   ERR(":Too many onexit() functions, or NULL function - not registered!\n");
146   return NULL;
147 }
148
149
150 /*********************************************************************
151  *                  exit          (CRTDLL.359)
152  */
153 void __cdecl CRTDLL_exit(DWORD ret)
154 {
155   TRACE(":exit code %ld\n",ret);
156   __CRTDLL__call_atexit();
157   CRTDLL__cexit();
158   ExitProcess(ret);
159 }
160
161
162 /*********************************************************************
163  *                   abort     (CRTDLL.335)
164  *
165  * Terminate the progam with an abnormal termination message. Returns
166  * 3 to the host OS.
167  */
168 VOID __cdecl CRTDLL_abort()
169 {
170   CRTDLL_fprintf(CRTDLL_stderr,"\nabnormal program termination\n");
171   CRTDLL__exit(3);
172 }
173
174
175 /*********************************************************************
176  *                  atexit           (CRTDLL.345)
177  *
178  * Register a function to be called when the process terminates.
179  */
180 INT __cdecl CRTDLL_atexit( atexit_function func)
181 {
182   return CRTDLL__onexit(func) == func ? 0 : -1;
183 }