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. */ 23PTR malloc PARAMS ((size_t)); 24 25static void xatexit_cleanup PARAMS ((void)); 26 27/* Pointer to function run by xexit. */ 28extern void (*_xexit_cleanup) PARAMS ((void)); 29 30#define XATEXIT_SIZE 32 31 32struct 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. */ 40static struct xatexit xatexit_first; 41 42/* Points to head of LIFO stack. */ 43static 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 48int 49xatexit (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 73static void 74xatexit_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} 83