intrcheck.c 2.88 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
#include <signal.h>
Guido van Rossum's avatar
Guido van Rossum committed
110 111 112
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
Guido van Rossum's avatar
Guido van Rossum committed
113

114
static int interrupted;
Guido van Rossum's avatar
Guido van Rossum committed
115

116
void
Thomas Wouters's avatar
Thomas Wouters committed
117
PyErr_SetInterrupt(void)
118 119 120 121
{
	interrupted = 1;
}

Thomas Wouters's avatar
Thomas Wouters committed
122 123 124 125 126 127 128
extern int PyErr_CheckSignals(void);

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

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

155
static void (*old_siginthandler)(int) = SIG_DFL;
156

Guido van Rossum's avatar
Guido van Rossum committed
157
void
Thomas Wouters's avatar
Thomas Wouters committed
158
PyOS_InitInterrupts(void)
Guido van Rossum's avatar
Guido van Rossum committed
159
{
160
	if ((old_siginthandler = signal(SIGINT, SIG_IGN)) != SIG_IGN)
Guido van Rossum's avatar
Guido van Rossum committed
161
		signal(SIGINT, intcatcher);
162
#ifdef HAVE_SIGINTERRUPT
163 164 165 166 167 168 169
	/* 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);
170
#endif /* HAVE_SIGINTERRUPT */
Guido van Rossum's avatar
Guido van Rossum committed
171 172
}

173
void
Thomas Wouters's avatar
Thomas Wouters committed
174
PyOS_FiniInterrupts(void)
175 176 177 178
{
	signal(SIGINT, old_siginthandler);
}

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

#endif /* !OK */
189 190

void
Thomas Wouters's avatar
Thomas Wouters committed
191
PyOS_AfterFork(void)
192
{
193 194 195
#ifdef WITH_THREAD
	PyEval_ReInitThreads();
#endif
196
}