(root)/
binutils-2.41/
libiberty/
xatexit.c
       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  void *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
      67  xatexit (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
      91  xatexit_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  }