Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  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
  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. }
  100.