Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

137 lines
3.3 KiB

  1. /***
  2. *onexit.c - save function for execution on exit
  3. *
  4. * Copyright (c) 1989-1993, Microsoft Corporation. All rights reserved.
  5. *
  6. *Purpose:
  7. * defines _onexit(), atexit() - save function for execution at exit
  8. *
  9. *Revision History:
  10. * 06-30-89 PHG module created, based on asm version
  11. * 03-15-90 GJF Replace _cdecl with _CALLTYPE1, added #include
  12. * <cruntime.h> and fixed the copyright. Also,
  13. * cleaned up the formatting a bit.
  14. * 05-21-90 GJF Fixed compiler warning.
  15. * 10-04-90 GJF New-style function declarators.
  16. * 12-28-90 SRW Added casts of func for Mips C Compiler
  17. * 01-21-91 GJF ANSI naming.
  18. * 09-09-91 GJF Revised for C++ needs.
  19. * 03-20-92 SKS Revamped for new initialization model
  20. * 04-23-92 DJM POSIX support.
  21. * 12-02-93 SKS Add __dllonexit for DLLs using CRTDLL.DLL
  22. *
  23. *******************************************************************************/
  24. #include <windows.h>
  25. #include <stdlib.h>
  26. #include <cruntime.h>
  27. #include <internal.h>
  28. #include <os2dll.h>
  29. #ifndef _CHICAGO_
  30. extern void DbgBreakPoint();
  31. #endif
  32. typedef void (_CALLTYPE1 *PF)(void); /* pointer to function */
  33. //
  34. // Keep this really simple: just have a vector of functions to be
  35. // called. We use a fixed length vector, since this is a special
  36. // application
  37. //
  38. #define MAX_EXIT_NOTIFICATIONS 48
  39. PF NotificationTable[MAX_EXIT_NOTIFICATIONS];
  40. extern PF * __onexitbegin;
  41. extern PF * __onexitend;
  42. /*
  43. * Define increment (in entries) for growing the _onexit/atexit table
  44. */
  45. #define ONEXITTBLINCR 4
  46. /***
  47. *_onexit(func), atexit(func) - add function to be executed upon exit
  48. *
  49. *Purpose:
  50. * The _onexit/atexit functions are passed a pointer to a function
  51. * to be called when the program terminate normally. Successive
  52. * calls create a register of functions that are executed last in,
  53. * first out.
  54. *
  55. *Entry:
  56. * void (*func)() - pointer to function to be executed upon exit
  57. *
  58. *Exit:
  59. * onexit:
  60. * Success - return pointer to user's function.
  61. * Error - return NULL pointer.
  62. * atexit:
  63. * Success - return 0.
  64. * Error - return non-zero value.
  65. *
  66. *Notes:
  67. * This routine depends on the behavior of _initterm() in CRT0DAT.C.
  68. * Specifically, _initterm() must not skip the address pointed to by
  69. * its first parameter, and must also stop before the address pointed
  70. * to by its second parameter. This is because _onexitbegin will point
  71. * to a valid address, and _onexitend will point at an invalid address.
  72. *
  73. *Exceptions:
  74. *
  75. *******************************************************************************/
  76. _onexit_t _CALLTYPE1 _onexit (
  77. _onexit_t func
  78. )
  79. {
  80. PF *p;
  81. _lockexit(); /* lock the exit code */
  82. // If the notification table hasn't been initialized, do so
  83. if (__onexitbegin == NULL) {
  84. __onexitbegin = __onexitend = NotificationTable;
  85. } else if (__onexitend >= &NotificationTable[MAX_EXIT_NOTIFICATIONS]) {
  86. // No space...
  87. #if DBG
  88. OutputDebugString ("(common\\cruntime\\onexit.c\\_onexit) Too many exit notifications!\n");
  89. DebugBreak ();
  90. #endif
  91. return NULL;
  92. }
  93. //
  94. // Put the new entry into the table and update the end-of-table
  95. // pointer.
  96. //
  97. *(__onexitend++) = (PF)func;
  98. _unlockexit();
  99. return func;
  100. }
  101. int _CALLTYPE1 atexit (
  102. PF func
  103. )
  104. {
  105. return (_onexit((_onexit_t)func) == NULL) ? -1 : 0;
  106. }