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 xatexit(void (* fn)(void))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 90 static void xatexit_cleanup(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