xatexit.c revision 130562
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} 102