1 | /*
|
---|
2 | * Copyright (c) 1990 Regents of the University of California.
|
---|
3 | * All rights reserved.
|
---|
4 | *
|
---|
5 | * %sccs.include.redist.c%
|
---|
6 | */
|
---|
7 |
|
---|
8 | /* Adapted from newlib/libc/stdlib/{,at}exit.[ch].
|
---|
9 | If you use xatexit, you must call xexit instead of exit. */
|
---|
10 |
|
---|
11 | #include "ansidecl.h"
|
---|
12 | #include "libiberty.h"
|
---|
13 |
|
---|
14 | #include <stdio.h>
|
---|
15 |
|
---|
16 | #ifdef __STDC__
|
---|
17 | #include <stddef.h>
|
---|
18 | #else
|
---|
19 | #define size_t unsigned long
|
---|
20 | #endif
|
---|
21 |
|
---|
22 | /* For systems with larger pointers than ints, this must be declared. */
|
---|
23 | PTR malloc PARAMS ((size_t));
|
---|
24 |
|
---|
25 | static void xatexit_cleanup PARAMS ((void));
|
---|
26 |
|
---|
27 | /* Pointer to function run by xexit. */
|
---|
28 | extern void (*_xexit_cleanup) PARAMS ((void));
|
---|
29 |
|
---|
30 | #define XATEXIT_SIZE 32
|
---|
31 |
|
---|
32 | struct xatexit {
|
---|
33 | struct xatexit *next; /* next in list */
|
---|
34 | int ind; /* next index in this table */
|
---|
35 | void (*fns[XATEXIT_SIZE]) PARAMS ((void)); /* the table itself */
|
---|
36 | };
|
---|
37 |
|
---|
38 | /* Allocate one struct statically to guarantee that we can register
|
---|
39 | at least a few handlers. */
|
---|
40 | static struct xatexit xatexit_first;
|
---|
41 |
|
---|
42 | /* Points to head of LIFO stack. */
|
---|
43 | static struct xatexit *xatexit_head = &xatexit_first;
|
---|
44 |
|
---|
45 | /* Register function FN to be run by xexit.
|
---|
46 | Return 0 if successful, -1 if not. */
|
---|
47 |
|
---|
48 | int
|
---|
49 | xatexit (fn)
|
---|
50 | void (*fn) PARAMS ((void));
|
---|
51 | {
|
---|
52 | register struct xatexit *p;
|
---|
53 |
|
---|
54 | /* Tell xexit to call xatexit_cleanup. */
|
---|
55 | if (!_xexit_cleanup)
|
---|
56 | _xexit_cleanup = xatexit_cleanup;
|
---|
57 |
|
---|
58 | p = xatexit_head;
|
---|
59 | if (p->ind >= XATEXIT_SIZE)
|
---|
60 | {
|
---|
61 | if ((p = (struct xatexit *) malloc (sizeof *p)) == NULL)
|
---|
62 | return -1;
|
---|
63 | p->ind = 0;
|
---|
64 | p->next = xatexit_head;
|
---|
65 | xatexit_head = p;
|
---|
66 | }
|
---|
67 | p->fns[p->ind++] = fn;
|
---|
68 | return 0;
|
---|
69 | }
|
---|
70 |
|
---|
71 | /* Call any cleanup functions. */
|
---|
72 |
|
---|
73 | static void
|
---|
74 | xatexit_cleanup ()
|
---|
75 | {
|
---|
76 | register struct xatexit *p;
|
---|
77 | register int n;
|
---|
78 |
|
---|
79 | for (p = xatexit_head; p; p = p->next)
|
---|
80 | for (n = p->ind; --n >= 0;)
|
---|
81 | (*p->fns[n]) ();
|
---|
82 | }
|
---|