Mercurial > hg > CbC > CbC_gcc
comparison libiberty/xatexit.c @ 0:a06113de4d67
first commit
author | kent <kent@cr.ie.u-ryukyu.ac.jp> |
---|---|
date | Fri, 17 Jul 2009 14:47:48 +0900 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:a06113de4d67 |
---|---|
1 /* | |
2 * Copyright (c) 1990 Regents of the University of California. | |
3 * All rights reserved. | |
4 * | |
5 * %sccs.include.redist.c% | |
6 */ | |
7 | |
8 | |
9 /* | |
10 | |
11 @deftypefun int xatexit (void (*@var{fn}) (void)) | |
12 | |
13 Behaves as the standard @code{atexit} function, but with no limit on | |
14 the number of registered functions. Returns 0 on success, or @minus{}1 on | |
15 failure. If you use @code{xatexit} to register functions, you must use | |
16 @code{xexit} to terminate your program. | |
17 | |
18 @end deftypefun | |
19 | |
20 */ | |
21 | |
22 /* Adapted from newlib/libc/stdlib/{,at}exit.[ch]. | |
23 If you use xatexit, you must call xexit instead of exit. */ | |
24 | |
25 #ifdef HAVE_CONFIG_H | |
26 #include "config.h" | |
27 #endif | |
28 #include "ansidecl.h" | |
29 #include "libiberty.h" | |
30 | |
31 #include <stdio.h> | |
32 | |
33 #include <stddef.h> | |
34 | |
35 #if VMS | |
36 #include <stdlib.h> | |
37 #include <unixlib.h> | |
38 #else | |
39 /* For systems with larger pointers than ints, this must be declared. */ | |
40 PTR malloc (size_t); | |
41 #endif | |
42 | |
43 static void xatexit_cleanup (void); | |
44 | |
45 /* Pointer to function run by xexit. */ | |
46 extern void (*_xexit_cleanup) (void); | |
47 | |
48 #define XATEXIT_SIZE 32 | |
49 | |
50 struct xatexit { | |
51 struct xatexit *next; /* next in list */ | |
52 int ind; /* next index in this table */ | |
53 void (*fns[XATEXIT_SIZE]) (void); /* the table itself */ | |
54 }; | |
55 | |
56 /* Allocate one struct statically to guarantee that we can register | |
57 at least a few handlers. */ | |
58 static struct xatexit xatexit_first; | |
59 | |
60 /* Points to head of LIFO stack. */ | |
61 static struct xatexit *xatexit_head = &xatexit_first; | |
62 | |
63 /* Register function FN to be run by xexit. | |
64 Return 0 if successful, -1 if not. */ | |
65 | |
66 int | |
67 xatexit (void (*fn) (void)) | |
68 { | |
69 register struct xatexit *p; | |
70 | |
71 /* Tell xexit to call xatexit_cleanup. */ | |
72 if (!_xexit_cleanup) | |
73 _xexit_cleanup = xatexit_cleanup; | |
74 | |
75 p = xatexit_head; | |
76 if (p->ind >= XATEXIT_SIZE) | |
77 { | |
78 if ((p = (struct xatexit *) malloc (sizeof *p)) == NULL) | |
79 return -1; | |
80 p->ind = 0; | |
81 p->next = xatexit_head; | |
82 xatexit_head = p; | |
83 } | |
84 p->fns[p->ind++] = fn; | |
85 return 0; | |
86 } | |
87 | |
88 /* Call any cleanup functions. */ | |
89 | |
90 static void | |
91 xatexit_cleanup (void) | |
92 { | |
93 register struct xatexit *p; | |
94 register int n; | |
95 | |
96 for (p = xatexit_head; p; p = p->next) | |
97 for (n = p->ind; --n >= 0;) | |
98 (*p->fns[n]) (); | |
99 } |