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