setjmp.c 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  1. /*++
  2. Copyright (c) 2013 Minoca Corp.
  3. This file is licensed under the terms of the GNU General Public License
  4. version 3. Alternative licensing terms are available. Contact
  5. info@minocacorp.com for details. See the LICENSE file at the root of this
  6. project for complete licensing information.
  7. Module Name:
  8. setjmp.c
  9. Abstract:
  10. This module implements the setjmp and longjmp functions used for non-local
  11. goto statements.
  12. Author:
  13. Evan Green 28-Jul-2013
  14. Environment:
  15. User Mode C Library
  16. --*/
  17. //
  18. // ------------------------------------------------------------------- Includes
  19. //
  20. #include "libcp.h"
  21. #include <setjmp.h>
  22. #include <signal.h>
  23. //
  24. // ---------------------------------------------------------------- Definitions
  25. //
  26. //
  27. // ------------------------------------------------------ Data Type Definitions
  28. //
  29. //
  30. // ----------------------------------------------- Internal Function Prototypes
  31. //
  32. void
  33. ClpLongJump (
  34. jmp_buf Environment,
  35. int Value
  36. );
  37. //
  38. // -------------------------------------------------------------------- Globals
  39. //
  40. //
  41. // ------------------------------------------------------------------ Functions
  42. //
  43. LIBC_API
  44. void
  45. longjmp (
  46. jmp_buf Environment,
  47. int Value
  48. )
  49. /*++
  50. Routine Description:
  51. This routine restores the environment saved by the most recent invocation
  52. of setjmp with the given environment buffer. If there is no such invocation,
  53. or if the function containing the invocation of setjmp has terminated in
  54. the interim, the behavior is undefined. Most likely, the app will crash
  55. spectacularly.
  56. Arguments:
  57. Environment - Supplies the pointer to the previously saved environment to
  58. restore.
  59. Value - Supplies the value to set as the return value from the setjmp
  60. function. If this value is 0, it will be set to 1.
  61. Return Value:
  62. None, this routine does not return.
  63. --*/
  64. {
  65. if (Value == 0) {
  66. Value = 1;
  67. }
  68. return ClpLongJump(Environment, Value);
  69. }
  70. LIBC_API
  71. void
  72. _longjmp (
  73. jmp_buf Environment,
  74. int Value
  75. )
  76. /*++
  77. Routine Description:
  78. This routine restores the environment saved by the most recent invocation
  79. of setjmp with the given environment buffer. If there is no such invocation,
  80. or if the function containing the invocation of setjmp has terminated in
  81. the interim, the behavior is undefined. Most likely, the app will crash
  82. spectacularly.
  83. Arguments:
  84. Environment - Supplies the pointer to the previously saved environment to
  85. restore.
  86. Value - Supplies the value to set as the return value from the setjmp
  87. function. If this value is 0, it will be set to 1.
  88. Return Value:
  89. None, this routine does not return.
  90. --*/
  91. {
  92. if (Value == 0) {
  93. Value = 1;
  94. }
  95. return ClpLongJump(Environment, Value);
  96. }
  97. LIBC_API
  98. void
  99. siglongjmp (
  100. sigjmp_buf Environment,
  101. int Value
  102. )
  103. /*++
  104. Routine Description:
  105. This routine restores the environment saved by the most recent invocation
  106. of setjmp with the given environment buffer. It works just like the longjmp
  107. function, except it also restores the signal mask if the given environment
  108. buffer was initialized with sigsetjmp with a non-zero save mask value.
  109. Arguments:
  110. Environment - Supplies the pointer to the previously saved environment to
  111. restore.
  112. Value - Supplies the value to set as the return value from the setjmp
  113. function. If this value is 0, it will be set to 1.
  114. Return Value:
  115. None, this routine does not return.
  116. --*/
  117. {
  118. if (Environment[0] != 0) {
  119. sigprocmask(SIG_SETMASK, (sigset_t *)&(Environment[1]), NULL);
  120. }
  121. if (Value == 0) {
  122. Value = 1;
  123. }
  124. return ClpLongJump(Environment, Value);
  125. }
  126. void
  127. ClpSetJump (
  128. jmp_buf Environment,
  129. int SaveMask
  130. )
  131. /*++
  132. Routine Description:
  133. This routine saves the calling environment into the given buffer for
  134. later use by longjmp.
  135. Arguments:
  136. Environment - Supplies the pointer to the environment to save the
  137. application context in.
  138. SaveMask - Supplies a value indicating if the caller would like the
  139. current signal mask to be saved in the environment as well.
  140. Return Value:
  141. 0 if this was the direct call to setjmp.
  142. Non-zero if this was a call from longjmp.
  143. --*/
  144. {
  145. Environment[0] = SaveMask;
  146. if (SaveMask != 0) {
  147. ASSERT(sizeof(sigset_t) <= sizeof(unsigned long long));
  148. sigprocmask(SIG_BLOCK, NULL, (sigset_t *)&(Environment[1]));
  149. }
  150. return;
  151. }
  152. //
  153. // --------------------------------------------------------- Internal Functions
  154. //