|
1 /* ATEXIT.C |
|
2 * |
|
3 * Portions Copyright (c) 1990-2006 Nokia Corporation and/or its subsidiary(-ies). |
|
4 * All rights reserved. |
|
5 */ |
|
6 |
|
7 /* |
|
8 * Copyright (c) 1990 Regents of the University of California. |
|
9 * All rights reserved. |
|
10 * |
|
11 * %sccs.include.redist.c% |
|
12 */ |
|
13 |
|
14 /* |
|
15 FUNCTION |
|
16 <<atexit>>---request execution of functions at program exit |
|
17 |
|
18 INDEX |
|
19 atexit |
|
20 |
|
21 ANSI_SYNOPSIS |
|
22 #include <stdlib.h> |
|
23 int atexit(void (*<[function]>)(void); |
|
24 |
|
25 TRAD_SYNOPSIS |
|
26 #include <stdlib.h> |
|
27 int atexit((<[function]>) |
|
28 void (*<[function]>)(); |
|
29 |
|
30 DESCRIPTION |
|
31 You can use <<atexit>> to enroll functions in a list of functions that |
|
32 will be called when your program terminates normally. The argument is |
|
33 a pointer to a user-defined function (which must not require arguments and |
|
34 must not return a result). |
|
35 |
|
36 The functions are kept in a LIFO stack; that is, the last function |
|
37 enrolled by <<atexit>> will be the first to execute when your program |
|
38 exits. |
|
39 |
|
40 There is no built-in limit to the number of functions you can enroll |
|
41 in this list; however, after every group of 32 functions is enrolled, |
|
42 <<atexit>> will call <<malloc>> to get space for the next part of the |
|
43 list. The initial list of 32 functions is statically allocated, so |
|
44 you can always count on at least that many slots available. |
|
45 |
|
46 RETURNS |
|
47 <<atexit>> returns <<0>> if it succeeds in enrolling your function, |
|
48 <<-1>> if it fails (possible only if no space was available for |
|
49 <<malloc>> to extend the list of functions or the library globals could not |
|
50 be allocated). |
|
51 |
|
52 PORTABILITY |
|
53 <<atexit>> is required by the ANSI standard, which also specifies that |
|
54 implementations must support enrolling at least 32 functions. |
|
55 |
|
56 Supporting OS subroutines required: <<close>>, <<fstat>>, <<isatty>>, |
|
57 <<lseek>>, <<read>>, <<sbrk>>, <<write>>. |
|
58 */ |
|
59 |
|
60 #include <stddef.h> |
|
61 #include <stdlib.h> |
|
62 #include <reent.h> |
|
63 |
|
64 /* |
|
65 * Register a function to be performed at exit. |
|
66 * NB. MSVC 5.0 has a built-in prototype for atexit, so we have to use a #define |
|
67 * to map the name atexit to _epoc32_atexit |
|
68 */ |
|
69 |
|
70 /* |
|
71 @return On Success, returns 0. |
|
72 On Failure, returns -1. |
|
73 */ |
|
74 |
|
75 EXPORT_C int |
|
76 _epoc32_atexit (void (*fn)(void)) |
|
77 { |
|
78 register struct _atexit *p; |
|
79 struct _reent *rp = _REENT2; |
|
80 if (!rp) |
|
81 return -1; // Memory for library globals is not allocated (errno not set). |
|
82 |
|
83 if ((p = rp->_atexit) == NULL) |
|
84 rp->_atexit = p = &rp->_atexit0; |
|
85 if (p->_ind >= _ATEXIT_SIZE) |
|
86 { |
|
87 if ((p = (struct _atexit *) malloc (sizeof *p)) == NULL) |
|
88 return -1; |
|
89 p->_ind = 0; |
|
90 p->_next = rp->_atexit; |
|
91 rp->_atexit = p; |
|
92 } |
|
93 p->_fns[p->_ind++] = fn; |
|
94 return 0; |
|
95 } |
|
96 |
|
97 EXPORT_C void |
|
98 _atexit_processing_r (struct _reent *rp) |
|
99 { |
|
100 register struct _atexit *p; |
|
101 register int n; |
|
102 |
|
103 for (p = rp->_atexit; p; p = p->_next) |
|
104 for (n = p->_ind; --n >= 0;) |
|
105 (*p->_fns[n]) (); |
|
106 if (rp->__cleanup) |
|
107 (*rp->__cleanup) (rp); |
|
108 } |