atexit.c 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  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. vfuncp called;
  21. void *argument;
  22. } __on_exit_table[MAXONEXIT];
  23. extern int __on_exit_count;
  24. /* End ATEXIT.H */
  25. #ifdef L_atexit
  26. vfuncp __cleanup;
  27. int atexit(ptr)
  28. vfuncp ptr;
  29. {
  30. if (__on_exit_count < 0 || __on_exit_count >= MAXONEXIT) {
  31. errno = ENOMEM;
  32. return -1;
  33. }
  34. __cleanup = __do_exit;
  35. if (ptr) {
  36. __on_exit_table[__on_exit_count].called = ptr;
  37. __on_exit_table[__on_exit_count].argument = 0;
  38. __on_exit_count++;
  39. }
  40. return 0;
  41. }
  42. #endif
  43. #ifdef L_on_exit
  44. int on_exit(ptr, arg)
  45. vfuncp ptr;
  46. void *arg;
  47. {
  48. if (__on_exit_count < 0 || __on_exit_count >= MAXONEXIT) {
  49. errno = ENOMEM;
  50. return -1;
  51. }
  52. __cleanup = __do_exit;
  53. if (ptr) {
  54. __on_exit_table[__on_exit_count].called = ptr;
  55. __on_exit_table[__on_exit_count].argument = arg;
  56. __on_exit_count++;
  57. }
  58. return 0;
  59. }
  60. #endif
  61. #ifdef L___do_exit
  62. int __on_exit_count = 0;
  63. struct exit_table __on_exit_table[MAXONEXIT];
  64. void __do_exit(rv)
  65. int rv;
  66. {
  67. register int count = __on_exit_count - 1;
  68. register vfuncp ptr;
  69. __on_exit_count = -1; /* ensure no more will be added */
  70. __cleanup = 0; /* Calling exit won't re-do this */
  71. /* In reverse order */
  72. for (; count >= 0; count--) {
  73. ptr = __on_exit_table[count].called;
  74. (*ptr) (rv, __on_exit_table[count].argument);
  75. }
  76. }
  77. #endif
  78. #ifdef L_exit
  79. void exit(rv)
  80. int rv;
  81. {
  82. if (__cleanup)
  83. __cleanup();
  84. _exit(rv);
  85. }
  86. #endif