atexit.c 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. /* Copyright (C) 1995,1996 Robert de Bath <rdebath@cix.compulink.co.uk>
  2. * This file is part of the Linux-8086 C library and is distributed
  3. * under the GNU Library General Public License.
  4. */
  5. /*
  6. * This deals with both the atexit and on_exit function calls
  7. *
  8. * Note calls installed with atexit are called with the same args as on_exit
  9. * fuctions; the void* is given the NULL value.
  10. *
  11. */
  12. #include <errno.h>
  13. /* ATEXIT.H */
  14. #define MAXONEXIT 20 /* AIUI Posix requires 10 */
  15. typedef void (*vfuncp) ();
  16. extern vfuncp __cleanup;
  17. extern void __do_exit();
  18. extern void _exit __P ((int __status)) __attribute__ ((__noreturn__));
  19. extern struct exit_table
  20. {
  21. vfuncp called;
  22. void *argument;
  23. }
  24. __on_exit_table[MAXONEXIT];
  25. extern int __on_exit_count;
  26. /* End ATEXIT.H */
  27. #ifdef L_atexit
  28. vfuncp __cleanup;
  29. int
  30. atexit(ptr)
  31. vfuncp ptr;
  32. {
  33. if( __on_exit_count < 0 || __on_exit_count >= MAXONEXIT)
  34. {
  35. errno = ENOMEM;
  36. return -1;
  37. }
  38. __cleanup = __do_exit;
  39. if( ptr )
  40. {
  41. __on_exit_table[__on_exit_count].called = ptr;
  42. __on_exit_table[__on_exit_count].argument = 0;
  43. __on_exit_count++;
  44. }
  45. return 0;
  46. }
  47. #endif
  48. #ifdef L_on_exit
  49. int
  50. on_exit(ptr, arg)
  51. vfuncp ptr;
  52. void *arg;
  53. {
  54. if( __on_exit_count < 0 || __on_exit_count >= MAXONEXIT)
  55. {
  56. errno = ENOMEM;
  57. return -1;
  58. }
  59. __cleanup = __do_exit;
  60. if( ptr )
  61. {
  62. __on_exit_table[__on_exit_count].called = ptr;
  63. __on_exit_table[__on_exit_count].argument = arg;
  64. __on_exit_count++;
  65. }
  66. return 0;
  67. }
  68. #endif
  69. #ifdef L___do_exit
  70. int __on_exit_count = 0;
  71. struct exit_table __on_exit_table[MAXONEXIT];
  72. void
  73. __do_exit(rv)
  74. int rv;
  75. {
  76. register int count = __on_exit_count-1;
  77. register vfuncp ptr;
  78. __on_exit_count = -1; /* ensure no more will be added */
  79. __cleanup = 0; /* Calling exit won't re-do this */
  80. /* In reverse order */
  81. for (; count >= 0; count--)
  82. {
  83. ptr = __on_exit_table[count].called;
  84. (*ptr) (rv, __on_exit_table[count].argument);
  85. }
  86. }
  87. #endif
  88. #ifdef L_exit
  89. void
  90. exit(rv)
  91. int rv;
  92. {
  93. if (__cleanup)
  94. __cleanup();
  95. _exit(rv);
  96. }
  97. #endif