Back to index

cell-binutils  2.17cvs20070401
xatexit.c
Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 1990 Regents of the University of California.
00003  * All rights reserved.
00004  *
00005  * %sccs.include.redist.c%
00006  */
00007 
00008 
00009 /*
00010 
00011 @deftypefun int xatexit (void (*@var{fn}) (void))
00012 
00013 Behaves as the standard @code{atexit} function, but with no limit on
00014 the number of registered functions.  Returns 0 on success, or @minus{}1 on
00015 failure.  If you use @code{xatexit} to register functions, you must use
00016 @code{xexit} to terminate your program.
00017 
00018 @end deftypefun
00019 
00020 */
00021 
00022 /* Adapted from newlib/libc/stdlib/{,at}exit.[ch].
00023    If you use xatexit, you must call xexit instead of exit.  */
00024 
00025 #ifdef HAVE_CONFIG_H
00026 #include "config.h"
00027 #endif
00028 #include "ansidecl.h"
00029 #include "libiberty.h"
00030 
00031 #include <stdio.h>
00032 
00033 #include <stddef.h>
00034 
00035 #if VMS
00036 #include <stdlib.h>
00037 #include <unixlib.h>
00038 #else
00039 /* For systems with larger pointers than ints, this must be declared.  */
00040 PTR malloc (size_t);
00041 #endif
00042 
00043 static void xatexit_cleanup (void);
00044 
00045 /* Pointer to function run by xexit.  */
00046 extern void (*_xexit_cleanup) (void);
00047 
00048 #define       XATEXIT_SIZE 32
00049 
00050 struct xatexit {
00051        struct xatexit *next;              /* next in list */
00052        int    ind;                 /* next index in this table */
00053        void   (*fns[XATEXIT_SIZE]) (void);       /* the table itself */
00054 };
00055 
00056 /* Allocate one struct statically to guarantee that we can register
00057    at least a few handlers.  */
00058 static struct xatexit xatexit_first;
00059 
00060 /* Points to head of LIFO stack.  */
00061 static struct xatexit *xatexit_head = &xatexit_first;
00062 
00063 /* Register function FN to be run by xexit.
00064    Return 0 if successful, -1 if not.  */
00065 
00066 int
00067 xatexit (void (*fn) (void))
00068 {
00069   register struct xatexit *p;
00070 
00071   /* Tell xexit to call xatexit_cleanup.  */
00072   if (!_xexit_cleanup)
00073     _xexit_cleanup = xatexit_cleanup;
00074 
00075   p = xatexit_head;
00076   if (p->ind >= XATEXIT_SIZE)
00077     {
00078       if ((p = (struct xatexit *) malloc (sizeof *p)) == NULL)
00079        return -1;
00080       p->ind = 0;
00081       p->next = xatexit_head;
00082       xatexit_head = p;
00083     }
00084   p->fns[p->ind++] = fn;
00085   return 0;
00086 }
00087 
00088 /* Call any cleanup functions.  */
00089 
00090 static void
00091 xatexit_cleanup (void)
00092 {
00093   register struct xatexit *p;
00094   register int n;
00095 
00096   for (p = xatexit_head; p; p = p->next)
00097     for (n = p->ind; --n >= 0;)
00098       (*p->fns[n]) ();
00099 }