/Parser/intrcheck.c

http://unladen-swallow.googlecode.com/ · C · 178 lines · 130 code · 40 blank · 8 comment · 9 complexity · 6d10bde9be1de65964ca34b07606a22f MD5 · raw file

  1. /* Check for interrupts */
  2. #include "Python.h"
  3. #include "pythread.h"
  4. #ifdef QUICKWIN
  5. #include <io.h>
  6. void
  7. PyOS_InitInterrupts(void)
  8. {
  9. }
  10. void
  11. PyOS_FiniInterrupts(void)
  12. {
  13. }
  14. int
  15. PyOS_InterruptOccurred(void)
  16. {
  17. _wyield();
  18. }
  19. #define OK
  20. #endif /* QUICKWIN */
  21. #if defined(_M_IX86) && !defined(__QNX__)
  22. #include <io.h>
  23. #endif
  24. #if defined(MSDOS) && !defined(QUICKWIN)
  25. #ifdef __GNUC__
  26. /* This is for DJGPP's GO32 extender. I don't know how to trap
  27. * control-C (There's no API for ctrl-C, and I don't want to mess with
  28. * the interrupt vectors.) However, this DOES catch control-break.
  29. * --Amrit
  30. */
  31. #include <go32.h>
  32. void
  33. PyOS_InitInterrupts(void)
  34. {
  35. _go32_want_ctrl_break(1 /* TRUE */);
  36. }
  37. void
  38. PyOS_FiniInterrupts(void)
  39. {
  40. }
  41. int
  42. PyOS_InterruptOccurred(void)
  43. {
  44. return _go32_was_ctrl_break_hit();
  45. }
  46. #else /* !__GNUC__ */
  47. /* This might work for MS-DOS (untested though): */
  48. void
  49. PyOS_InitInterrupts(void)
  50. {
  51. }
  52. void
  53. PyOS_FiniInterrupts(void)
  54. {
  55. }
  56. int
  57. PyOS_InterruptOccurred(void)
  58. {
  59. int interrupted = 0;
  60. while (kbhit()) {
  61. if (getch() == '\003')
  62. interrupted = 1;
  63. }
  64. return interrupted;
  65. }
  66. #endif /* __GNUC__ */
  67. #define OK
  68. #endif /* MSDOS && !QUICKWIN */
  69. #ifndef OK
  70. /* Default version -- for real operating systems and for Standard C */
  71. #include <stdio.h>
  72. #include <string.h>
  73. #include <signal.h>
  74. static int interrupted;
  75. void
  76. PyErr_SetInterrupt(void)
  77. {
  78. interrupted = 1;
  79. }
  80. extern int PyErr_CheckSignals(void);
  81. static int
  82. checksignals_witharg(void * arg)
  83. {
  84. return PyErr_CheckSignals();
  85. }
  86. static void
  87. intcatcher(int sig)
  88. {
  89. extern void Py_Exit(int);
  90. static char message[] =
  91. "python: to interrupt a truly hanging Python program, interrupt once more.\n";
  92. switch (interrupted++) {
  93. case 0:
  94. break;
  95. case 1:
  96. #ifdef RISCOS
  97. fprintf(stderr, message);
  98. #else
  99. write(2, message, strlen(message));
  100. #endif
  101. break;
  102. case 2:
  103. interrupted = 0;
  104. Py_Exit(1);
  105. break;
  106. }
  107. PyOS_setsig(SIGINT, intcatcher);
  108. Py_AddPendingCall(checksignals_witharg, NULL);
  109. }
  110. static void (*old_siginthandler)(int) = SIG_DFL;
  111. void
  112. PyOS_InitInterrupts(void)
  113. {
  114. if ((old_siginthandler = PyOS_setsig(SIGINT, SIG_IGN)) != SIG_IGN)
  115. PyOS_setsig(SIGINT, intcatcher);
  116. }
  117. void
  118. PyOS_FiniInterrupts(void)
  119. {
  120. PyOS_setsig(SIGINT, old_siginthandler);
  121. }
  122. int
  123. PyOS_InterruptOccurred(void)
  124. {
  125. if (!interrupted)
  126. return 0;
  127. interrupted = 0;
  128. return 1;
  129. }
  130. #endif /* !OK */
  131. void
  132. PyOS_AfterFork(void)
  133. {
  134. #ifdef WITH_THREAD
  135. PyEval_ReInitThreads();
  136. PyThread_ReInitTLS();
  137. #endif
  138. }