ucontext.c 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. /*++
  2. Copyright (c) 2016 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. ucontext.c
  9. Abstract:
  10. This module implements architecture independent functions related to
  11. manipulating ucontext structures.
  12. Author:
  13. Evan Green 8-Sep-2016
  14. Environment:
  15. User Mode C Library
  16. --*/
  17. //
  18. // ------------------------------------------------------------------- Includes
  19. //
  20. #include "libcp.h"
  21. #include <errno.h>
  22. #include <signal.h>
  23. #include <stdlib.h>
  24. #include <ucontext.h>
  25. //
  26. // ---------------------------------------------------------------- Definitions
  27. //
  28. //
  29. // ------------------------------------------------------ Data Type Definitions
  30. //
  31. //
  32. // ----------------------------------------------- Internal Function Prototypes
  33. //
  34. //
  35. // -------------------------------------------------------------------- Globals
  36. //
  37. //
  38. // ------------------------------------------------------------------ Functions
  39. //
  40. LIBC_API
  41. int
  42. swapcontext (
  43. ucontext_t *OldContext,
  44. ucontext_t *Context
  45. )
  46. /*++
  47. Routine Description:
  48. This routine saves the current context, and sets the given new context
  49. with a backlink to the original context.
  50. Arguments:
  51. OldContext - Supplies a pointer where the currently running context will
  52. be saved on success.
  53. Context - Supplies a pointer to the new context to apply. A link to the
  54. context running before this call will be saved in this context.
  55. Return Value:
  56. 0 on success.
  57. -1 on failure, and errno will be set contain more information.
  58. --*/
  59. {
  60. int Status;
  61. if ((OldContext == NULL) || (Context == NULL)) {
  62. errno = EINVAL;
  63. return -1;
  64. }
  65. OldContext->uc_flags &= ~SIGNAL_CONTEXT_FLAG_SWAPPED;
  66. Status = getcontext(OldContext);
  67. //
  68. // Everything below this comment actually runs twice. The first time it is
  69. // run the swapped flag is just recently cleared. In that case go run the
  70. // new context. When the new context returns (via makecontext's function
  71. // returning), it will return right here. The swapped flag will have been
  72. // set so this routine doesn't go set the same context again.
  73. //
  74. if ((Status == 0) &&
  75. ((OldContext->uc_flags & SIGNAL_CONTEXT_FLAG_SWAPPED) == 0)) {
  76. OldContext->uc_flags |= SIGNAL_CONTEXT_FLAG_SWAPPED;
  77. Status = setcontext(Context);
  78. }
  79. return Status;
  80. }
  81. __NO_RETURN
  82. VOID
  83. ClpContextEnd (
  84. ucontext_t *Context
  85. )
  86. /*++
  87. Routine Description:
  88. This routine is called after the function entered via makecontext +
  89. setcontext returns. It sets the next context, or exits the process if there
  90. is no next context.
  91. Arguments:
  92. Context - Supplies a pointer to the context.
  93. Return Value:
  94. This routine does not return. It either sets a new context or exits the
  95. process.
  96. --*/
  97. {
  98. if (Context->uc_link == NULL) {
  99. exit(0);
  100. }
  101. setcontext((const ucontext_t *)Context->uc_link);
  102. abort();
  103. }
  104. //
  105. // --------------------------------------------------------- Internal Functions
  106. //