Home | History | Annotate | Download | only in Parser
      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
     12 PyOS_InitInterrupts(void)
     13 {
     14 }
     15 
     16 void
     17 PyOS_FiniInterrupts(void)
     18 {
     19 }
     20 
     21 int
     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
     48 PyOS_InitInterrupts(void)
     49 {
     50     _go32_want_ctrl_break(1 /* TRUE */);
     51 }
     52 
     53 void
     54 PyOS_FiniInterrupts(void)
     55 {
     56 }
     57 
     58 int
     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
     69 PyOS_InitInterrupts(void)
     70 {
     71 }
     72 
     73 void
     74 PyOS_FiniInterrupts(void)
     75 {
     76 }
     77 
     78 int
     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
    107 PyErr_SetInterrupt(void)
    108 {
    109     interrupted = 1;
    110 }
    111 
    112 extern int PyErr_CheckSignals(void);
    113 
    114 static int
    115 checksignals_witharg(void * arg)
    116 {
    117     return PyErr_CheckSignals();
    118 }
    119 
    120 static void
    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
    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
    155 PyOS_FiniInterrupts(void)
    156 {
    157     PyOS_setsig(SIGINT, old_siginthandler);
    158 }
    159 
    160 int
    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
    172 PyOS_AfterFork(void)
    173 {
    174 #ifdef WITH_THREAD
    175     PyEval_ReInitThreads();
    176     PyThread_ReInitTLS();
    177 #endif
    178 }
    179