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