/Parser/intrcheck.c
C | 178 lines | 130 code | 40 blank | 8 comment | 9 complexity | 6d10bde9be1de65964ca34b07606a22f MD5 | raw file
1 2/* Check for interrupts */ 3 4#include "Python.h" 5#include "pythread.h" 6 7#ifdef QUICKWIN 8 9#include <io.h> 10 11void 12PyOS_InitInterrupts(void) 13{ 14} 15 16void 17PyOS_FiniInterrupts(void) 18{ 19} 20 21int 22PyOS_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 47void 48PyOS_InitInterrupts(void) 49{ 50 _go32_want_ctrl_break(1 /* TRUE */); 51} 52 53void 54PyOS_FiniInterrupts(void) 55{ 56} 57 58int 59PyOS_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 68void 69PyOS_InitInterrupts(void) 70{ 71} 72 73void 74PyOS_FiniInterrupts(void) 75{ 76} 77 78int 79PyOS_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 104static int interrupted; 105 106void 107PyErr_SetInterrupt(void) 108{ 109 interrupted = 1; 110} 111 112extern int PyErr_CheckSignals(void); 113 114static int 115checksignals_witharg(void * arg) 116{ 117 return PyErr_CheckSignals(); 118} 119 120static void 121intcatcher(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 145static void (*old_siginthandler)(int) = SIG_DFL; 146 147void 148PyOS_InitInterrupts(void) 149{ 150 if ((old_siginthandler = PyOS_setsig(SIGINT, SIG_IGN)) != SIG_IGN) 151 PyOS_setsig(SIGINT, intcatcher); 152} 153 154void 155PyOS_FiniInterrupts(void) 156{ 157 PyOS_setsig(SIGINT, old_siginthandler); 158} 159 160int 161PyOS_InterruptOccurred(void) 162{ 163 if (!interrupted) 164 return 0; 165 interrupted = 0; 166 return 1; 167} 168 169#endif /* !OK */ 170 171void 172PyOS_AfterFork(void) 173{ 174#ifdef WITH_THREAD 175 PyEval_ReInitThreads(); 176 PyThread_ReInitTLS(); 177#endif 178}