source: branches/libc-0.6/src/binutils/libiberty/xatexit.c

Last change on this file was 610, checked in by bird, 22 years ago

This commit was generated by cvs2svn to compensate for changes in r609,
which included commits to RCS files with non-trunk default branches.

  • Property cvs2svn:cvs-rev set to 1.1.1.2
  • Property svn:eol-style set to native
  • Property svn:executable set to *
File size: 2.1 KB
Line 
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
13Behaves as the standard @code{atexit} function, but with no limit on
14the number of registered functions. Returns 0 on success, or @minus{}1 on
15failure. 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#include "ansidecl.h"
26#include "libiberty.h"
27
28#include <stdio.h>
29
30#ifdef ANSI_PROTOTYPES
31#include <stddef.h>
32#else
33#define size_t unsigned long
34#endif
35
36#if VMS
37#include <stdlib.h>
38#include <unixlib.h>
39#else
40/* For systems with larger pointers than ints, this must be declared. */
41PTR malloc PARAMS ((size_t));
42#endif
43
44static void xatexit_cleanup PARAMS ((void));
45
46/* Pointer to function run by xexit. */
47extern void (*_xexit_cleanup) PARAMS ((void));
48
49#define XATEXIT_SIZE 32
50
51struct xatexit {
52 struct xatexit *next; /* next in list */
53 int ind; /* next index in this table */
54 void (*fns[XATEXIT_SIZE]) PARAMS ((void)); /* the table itself */
55};
56
57/* Allocate one struct statically to guarantee that we can register
58 at least a few handlers. */
59static struct xatexit xatexit_first;
60
61/* Points to head of LIFO stack. */
62static struct xatexit *xatexit_head = &xatexit_first;
63
64/* Register function FN to be run by xexit.
65 Return 0 if successful, -1 if not. */
66
67int
68xatexit (fn)
69 void (*fn) PARAMS ((void));
70{
71 register struct xatexit *p;
72
73 /* Tell xexit to call xatexit_cleanup. */
74 if (!_xexit_cleanup)
75 _xexit_cleanup = xatexit_cleanup;
76
77 p = xatexit_head;
78 if (p->ind >= XATEXIT_SIZE)
79 {
80 if ((p = (struct xatexit *) malloc (sizeof *p)) == NULL)
81 return -1;
82 p->ind = 0;
83 p->next = xatexit_head;
84 xatexit_head = p;
85 }
86 p->fns[p->ind++] = fn;
87 return 0;
88}
89
90/* Call any cleanup functions. */
91
92static void
93xatexit_cleanup ()
94{
95 register struct xatexit *p;
96 register int n;
97
98 for (p = xatexit_head; p; p = p->next)
99 for (n = p->ind; --n >= 0;)
100 (*p->fns[n]) ();
101}
Note: See TracBrowser for help on using the repository browser.