Updated for 2.1b2 distribution.
[python/dscho.git] / Parser / intrcheck.c
blob686e030e601d00b87a8d8d0bd524cb3b37371c53
2 /* Check for interrupts */
4 #include "Python.h"
6 #ifdef QUICKWIN
8 #include <io.h>
10 void
11 PyOS_InitInterrupts(void)
15 void
16 PyOS_FiniInterrupts(void)
20 int
21 PyOS_InterruptOccurred(void)
23 _wyield();
26 #define OK
28 #endif /* QUICKWIN */
30 #if defined(_M_IX86) && !defined(__QNX__)
31 #include <io.h>
32 #endif
34 #if defined(MSDOS) && !defined(QUICKWIN)
36 #ifdef __GNUC__
38 /* This is for DJGPP's GO32 extender. I don't know how to trap
39 * control-C (There's no API for ctrl-C, and I don't want to mess with
40 * the interrupt vectors.) However, this DOES catch control-break.
41 * --Amrit
44 #include <go32.h>
46 void
47 PyOS_InitInterrupts(void)
49 _go32_want_ctrl_break(1 /* TRUE */);
52 void
53 PyOS_FiniInterrupts(void)
57 int
58 PyOS_InterruptOccurred(void)
60 return _go32_was_ctrl_break_hit();
63 #else /* !__GNUC__ */
65 /* This might work for MS-DOS (untested though): */
67 void
68 PyOS_InitInterrupts(void)
72 void
73 PyOS_FiniInterrupts(void)
77 int
78 PyOS_InterruptOccurred(void)
80 int interrupted = 0;
81 while (kbhit()) {
82 if (getch() == '\003')
83 interrupted = 1;
85 return interrupted;
88 #endif /* __GNUC__ */
90 #define OK
92 #endif /* MSDOS && !QUICKWIN */
95 #ifdef macintosh
97 /* The Mac interrupt code has moved to macglue.c */
98 #define OK
100 #endif /* macintosh */
103 #ifndef OK
105 /* Default version -- for real operating systems and for Standard C */
107 #include <stdio.h>
108 #include <string.h>
109 #include <signal.h>
110 #ifdef HAVE_UNISTD_H
111 #include <unistd.h>
112 #endif
114 static int interrupted;
116 void
117 PyErr_SetInterrupt(void)
119 interrupted = 1;
122 extern int PyErr_CheckSignals(void);
124 static int
125 checksignals_witharg(void * arg)
127 return PyErr_CheckSignals();
130 static void
131 intcatcher(int sig)
133 extern void Py_Exit(int);
134 static char message[] =
135 "python: to interrupt a truly hanging Python program, interrupt once more.\n";
136 switch (interrupted++) {
137 case 0:
138 break;
139 case 1:
140 #ifdef RISCOS
141 fprintf(stderr, message);
142 #else
143 write(2, message, strlen(message));
144 #endif
145 break;
146 case 2:
147 interrupted = 0;
148 Py_Exit(1);
149 break;
151 signal(SIGINT, intcatcher);
152 Py_AddPendingCall(checksignals_witharg, NULL);
155 static void (*old_siginthandler)(int) = SIG_DFL;
157 void
158 PyOS_InitInterrupts(void)
160 if ((old_siginthandler = signal(SIGINT, SIG_IGN)) != SIG_IGN)
161 signal(SIGINT, intcatcher);
162 #ifdef HAVE_SIGINTERRUPT
163 /* This is for SunOS and other modern BSD derivatives.
164 It means that system calls (like read()) are not restarted
165 after an interrupt. This is necessary so interrupting a
166 read() or readline() call works as expected.
167 XXX On old BSD (pure 4.2 or older) you may have to do this
168 differently! */
169 siginterrupt(SIGINT, 1);
170 #endif /* HAVE_SIGINTERRUPT */
173 void
174 PyOS_FiniInterrupts(void)
176 signal(SIGINT, old_siginthandler);
180 PyOS_InterruptOccurred(void)
182 if (!interrupted)
183 return 0;
184 interrupted = 0;
185 return 1;
188 #endif /* !OK */
190 void
191 PyOS_AfterFork(void)
193 #ifdef WITH_THREAD
194 PyEval_ReInitThreads();
195 #endif