intrcheck.c 2.83 KB
Newer Older
1

Guido van Rossum's avatar
Guido van Rossum committed
2 3
/* Check for interrupts */

4
#include "Python.h"
5

6 7 8 9 10
#ifdef QUICKWIN

#include <io.h>

void
Thomas Wouters's avatar
Thomas Wouters committed
11
PyOS_InitInterrupts(void)
12 13 14
{
}

15
void
Thomas Wouters's avatar
Thomas Wouters committed
16
PyOS_FiniInterrupts(void)
17 18 19
{
}

20
int
Thomas Wouters's avatar
Thomas Wouters committed
21
PyOS_InterruptOccurred(void)
22 23 24 25 26 27 28 29
{
	_wyield();
}

#define OK

#endif /* QUICKWIN */

30
#if defined(_M_IX86) && !defined(__QNX__)
31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
#include <io.h>
#endif

#if defined(MSDOS) && !defined(QUICKWIN)

#ifdef __GNUC__

/* This is for DJGPP's GO32 extender.  I don't know how to trap
 * control-C  (There's no API for ctrl-C, and I don't want to mess with
 * the interrupt vectors.)  However, this DOES catch control-break.
 * --Amrit
 */

#include <go32.h>

void
Thomas Wouters's avatar
Thomas Wouters committed
47
PyOS_InitInterrupts(void)
48 49 50 51
{
	_go32_want_ctrl_break(1 /* TRUE */);
}

52
void
Thomas Wouters's avatar
Thomas Wouters committed
53
PyOS_FiniInterrupts(void)
54 55 56
{
}

57
int
Thomas Wouters's avatar
Thomas Wouters committed
58
PyOS_InterruptOccurred(void)
59 60 61 62 63
{
	return _go32_was_ctrl_break_hit();
}

#else /* !__GNUC__ */
Guido van Rossum's avatar
Guido van Rossum committed
64

Guido van Rossum's avatar
Guido van Rossum committed
65
/* This might work for MS-DOS (untested though): */
Guido van Rossum's avatar
Guido van Rossum committed
66 67

void
Thomas Wouters's avatar
Thomas Wouters committed
68
PyOS_InitInterrupts(void)
Guido van Rossum's avatar
Guido van Rossum committed
69 70 71
{
}

72
void
Thomas Wouters's avatar
Thomas Wouters committed
73
PyOS_FiniInterrupts(void)
74 75 76
{
}

Guido van Rossum's avatar
Guido van Rossum committed
77
int
Thomas Wouters's avatar
Thomas Wouters committed
78
PyOS_InterruptOccurred(void)
Guido van Rossum's avatar
Guido van Rossum committed
79 80 81 82 83 84 85 86 87
{
	int interrupted = 0;
	while (kbhit()) {
		if (getch() == '\003')
			interrupted = 1;
	}
	return interrupted;
}

88 89
#endif /* __GNUC__ */

Guido van Rossum's avatar
Guido van Rossum committed
90 91
#define OK

92
#endif /* MSDOS && !QUICKWIN */
Guido van Rossum's avatar
Guido van Rossum committed
93 94


95
#ifdef macintosh
Guido van Rossum's avatar
Guido van Rossum committed
96

97
/* The Mac interrupt code has moved to macglue.c */
Guido van Rossum's avatar
Guido van Rossum committed
98 99
#define OK

100
#endif /* macintosh */
Guido van Rossum's avatar
Guido van Rossum committed
101 102 103 104


#ifndef OK

Guido van Rossum's avatar
Guido van Rossum committed
105
/* Default version -- for real operating systems and for Standard C */
Guido van Rossum's avatar
Guido van Rossum committed
106 107

#include <stdio.h>
108
#include <string.h>
Guido van Rossum's avatar
Guido van Rossum committed
109 110
#include <signal.h>

111
static int interrupted;
Guido van Rossum's avatar
Guido van Rossum committed
112

113
void
Thomas Wouters's avatar
Thomas Wouters committed
114
PyErr_SetInterrupt(void)
115 116 117 118
{
	interrupted = 1;
}

Thomas Wouters's avatar
Thomas Wouters committed
119 120 121 122 123 124 125
extern int PyErr_CheckSignals(void);

static int
checksignals_witharg(void * arg)
{
	return PyErr_CheckSignals();
}
126

127
static void
Thomas Wouters's avatar
Thomas Wouters committed
128
intcatcher(int sig)
Guido van Rossum's avatar
Guido van Rossum committed
129
{
130
	extern void Py_Exit(int);
131 132 133 134 135 136
	static char message[] =
"python: to interrupt a truly hanging Python program, interrupt once more.\n";
	switch (interrupted++) {
	case 0:
		break;
	case 1:
137 138 139
#ifdef RISCOS
		fprintf(stderr, message);
#else
140
		write(2, message, strlen(message));
141
#endif
142 143 144
		break;
	case 2:
		interrupted = 0;
145
		Py_Exit(1);
146 147
		break;
	}
Guido van Rossum's avatar
Guido van Rossum committed
148
	signal(SIGINT, intcatcher);
Thomas Wouters's avatar
Thomas Wouters committed
149
	Py_AddPendingCall(checksignals_witharg, NULL);
Guido van Rossum's avatar
Guido van Rossum committed
150 151
}

152
static void (*old_siginthandler)(int) = SIG_DFL;
153

Guido van Rossum's avatar
Guido van Rossum committed
154
void
Thomas Wouters's avatar
Thomas Wouters committed
155
PyOS_InitInterrupts(void)
Guido van Rossum's avatar
Guido van Rossum committed
156
{
157
	if ((old_siginthandler = signal(SIGINT, SIG_IGN)) != SIG_IGN)
Guido van Rossum's avatar
Guido van Rossum committed
158
		signal(SIGINT, intcatcher);
159
#ifdef HAVE_SIGINTERRUPT
160 161 162 163 164 165 166
	/* This is for SunOS and other modern BSD derivatives.
	   It means that system calls (like read()) are not restarted
	   after an interrupt.  This is necessary so interrupting a
	   read() or readline() call works as expected.
	   XXX On old BSD (pure 4.2 or older) you may have to do this
	   differently! */
	siginterrupt(SIGINT, 1);
167
#endif /* HAVE_SIGINTERRUPT */
Guido van Rossum's avatar
Guido van Rossum committed
168 169
}

170
void
Thomas Wouters's avatar
Thomas Wouters committed
171
PyOS_FiniInterrupts(void)
172 173 174 175
{
	signal(SIGINT, old_siginthandler);
}

Guido van Rossum's avatar
Guido van Rossum committed
176
int
Thomas Wouters's avatar
Thomas Wouters committed
177
PyOS_InterruptOccurred(void)
Guido van Rossum's avatar
Guido van Rossum committed
178 179 180 181 182 183 184 185
{
	if (!interrupted)
		return 0;
	interrupted = 0;
	return 1;
}

#endif /* !OK */
186 187

void
Thomas Wouters's avatar
Thomas Wouters committed
188
PyOS_AfterFork(void)
189
{
190 191 192
#ifdef WITH_THREAD
	PyEval_ReInitThreads();
#endif
193
}