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#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. */ 40PTR malloc (size_t); 41#endif 42 43static void xatexit_cleanup (void); 44 45/* Pointer to function run by xexit. */ 46extern void (*_xexit_cleanup) (void); 47 48#define XATEXIT_SIZE 32 49 50struct 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. */ 58static struct xatexit xatexit_first; 59 60/* Points to head of LIFO stack. */ 61static 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 66int 67xatexit (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 90static void 91xatexit_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} 100