blob: e23b126d52a58fdefb5e23fcb3e8c05767627d8a [file] [log] [blame]
Thomas Woutersed03b412007-08-28 21:37:11 +00001import unittest
Benjamin Petersonee8712c2008-05-20 21:35:26 +00002from test import support
Raymond Hettinger722d8c32009-06-18 22:21:03 +00003from contextlib import closing
Christian Heimescc47b052008-03-25 14:56:36 +00004import gc
Christian Heimes4fbc72b2008-03-22 00:47:35 +00005import pickle
6import select
Guido van Rossum4f17e3e1995-03-16 15:07:38 +00007import signal
Victor Stinnerd49b1f12011-05-08 02:03:15 +02008import struct
Christian Heimes4fbc72b2008-03-22 00:47:35 +00009import subprocess
10import traceback
Christian Heimesc06950e2008-02-28 21:17:00 +000011import sys, os, time, errno
Victor Stinnerd6284962011-06-20 23:28:09 +020012from test.script_helper import assert_python_ok, spawn_python
Victor Stinnerb3e72192011-05-08 01:46:11 +020013try:
14 import threading
15except ImportError:
16 threading = None
Christian Heimesc06950e2008-02-28 21:17:00 +000017
Brian Curtin912443c2010-09-06 16:10:04 +000018if sys.platform in ('os2', 'riscos'):
19 raise unittest.SkipTest("Can't test signal on %s" % sys.platform)
Christian Heimesc06950e2008-02-28 21:17:00 +000020
Guido van Rossumcc5a91d1997-04-16 00:29:15 +000021
Armin Rigo8b2cbfd2004-08-07 21:27:43 +000022class HandlerBCalled(Exception):
23 pass
Guido van Rossum4f17e3e1995-03-16 15:07:38 +000024
Christian Heimes4fbc72b2008-03-22 00:47:35 +000025
26def exit_subprocess():
27 """Use os._exit(0) to exit the current subprocess.
28
29 Otherwise, the test catches the SystemExit and continues executing
30 in parallel with the original test, so you wind up with an
31 exponential number of tests running concurrently.
32 """
33 os._exit(0)
34
35
Benjamin Petersonad9d48d2008-04-02 21:49:44 +000036def ignoring_eintr(__func, *args, **kwargs):
37 try:
38 return __func(*args, **kwargs)
Neal Norwitzf5c7c2e2008-04-05 04:47:45 +000039 except EnvironmentError as e:
40 if e.errno != errno.EINTR:
Benjamin Petersonad9d48d2008-04-02 21:49:44 +000041 raise
42 return None
43
44
Brian Curtin3f004b12010-08-06 19:34:52 +000045@unittest.skipIf(sys.platform == "win32", "Not valid on Windows")
Thomas Woutersed03b412007-08-28 21:37:11 +000046class InterProcessSignalTests(unittest.TestCase):
47 MAX_DURATION = 20 # Entire test should last at most 20 sec.
Guido van Rossum4f17e3e1995-03-16 15:07:38 +000048
Christian Heimescc47b052008-03-25 14:56:36 +000049 def setUp(self):
50 self.using_gc = gc.isenabled()
51 gc.disable()
52
53 def tearDown(self):
54 if self.using_gc:
55 gc.enable()
56
Christian Heimes5e696852008-04-09 08:37:03 +000057 def format_frame(self, frame, limit=None):
58 return ''.join(traceback.format_stack(frame, limit=limit))
59
60 def handlerA(self, signum, frame):
Thomas Woutersed03b412007-08-28 21:37:11 +000061 self.a_called = True
Guido van Rossum4f17e3e1995-03-16 15:07:38 +000062
Christian Heimes5e696852008-04-09 08:37:03 +000063 def handlerB(self, signum, frame):
Thomas Woutersed03b412007-08-28 21:37:11 +000064 self.b_called = True
Christian Heimes5e696852008-04-09 08:37:03 +000065 raise HandlerBCalled(signum, self.format_frame(frame))
Neal Norwitz9730bcb2006-01-23 07:50:06 +000066
Christian Heimes4fbc72b2008-03-22 00:47:35 +000067 def wait(self, child):
68 """Wait for child to finish, ignoring EINTR."""
69 while True:
70 try:
71 child.wait()
72 return
73 except OSError as e:
74 if e.errno != errno.EINTR:
75 raise
Fred Drake004d5e62000-10-23 17:22:08 +000076
Christian Heimes4fbc72b2008-03-22 00:47:35 +000077 def run_test(self):
78 # Install handlers. This function runs in a sub-process, so we
79 # don't worry about re-setting the default handlers.
80 signal.signal(signal.SIGHUP, self.handlerA)
81 signal.signal(signal.SIGUSR1, self.handlerB)
82 signal.signal(signal.SIGUSR2, signal.SIG_IGN)
83 signal.signal(signal.SIGALRM, signal.default_int_handler)
Michael W. Hudson5c26e862004-06-11 18:09:28 +000084
Christian Heimes4fbc72b2008-03-22 00:47:35 +000085 # Variables the signals will modify:
86 self.a_called = False
87 self.b_called = False
Thomas Wouters00ee7ba2006-08-21 19:07:27 +000088
Christian Heimes4fbc72b2008-03-22 00:47:35 +000089 # Let the sub-processes know who to send signals to.
90 pid = os.getpid()
Thomas Wouters00ee7ba2006-08-21 19:07:27 +000091
Benjamin Petersonad9d48d2008-04-02 21:49:44 +000092 child = ignoring_eintr(subprocess.Popen, ['kill', '-HUP', str(pid)])
93 if child:
94 self.wait(child)
95 if not self.a_called:
96 time.sleep(1) # Give the signal time to be delivered.
Christian Heimes4fbc72b2008-03-22 00:47:35 +000097 self.assertTrue(self.a_called)
98 self.assertFalse(self.b_called)
99 self.a_called = False
Thomas Wouters00ee7ba2006-08-21 19:07:27 +0000100
Christian Heimes5e696852008-04-09 08:37:03 +0000101 # Make sure the signal isn't delivered while the previous
102 # Popen object is being destroyed, because __del__ swallows
103 # exceptions.
104 del child
Thomas Woutersed03b412007-08-28 21:37:11 +0000105 try:
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000106 child = subprocess.Popen(['kill', '-USR1', str(pid)])
107 # This wait should be interrupted by the signal's exception.
108 self.wait(child)
Benjamin Petersonad9d48d2008-04-02 21:49:44 +0000109 time.sleep(1) # Give the signal time to be delivered.
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000110 self.fail('HandlerBCalled exception not thrown')
111 except HandlerBCalled:
112 self.assertTrue(self.b_called)
113 self.assertFalse(self.a_called)
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000114
Benjamin Petersonad9d48d2008-04-02 21:49:44 +0000115 child = ignoring_eintr(subprocess.Popen, ['kill', '-USR2', str(pid)])
116 if child:
117 self.wait(child) # Nothing should happen.
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000118
119 try:
120 signal.alarm(1)
121 # The race condition in pause doesn't matter in this case,
122 # since alarm is going to raise a KeyboardException, which
123 # will skip the call.
124 signal.pause()
Benjamin Petersonad9d48d2008-04-02 21:49:44 +0000125 # But if another signal arrives before the alarm, pause
126 # may return early.
127 time.sleep(1)
Thomas Woutersed03b412007-08-28 21:37:11 +0000128 except KeyboardInterrupt:
Victor Stinner3a7f0f02011-05-08 02:10:36 +0200129 pass
Thomas Woutersed03b412007-08-28 21:37:11 +0000130 except:
Benjamin Petersonad9d48d2008-04-02 21:49:44 +0000131 self.fail("Some other exception woke us from pause: %s" %
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000132 traceback.format_exc())
133 else:
Benjamin Petersonad9d48d2008-04-02 21:49:44 +0000134 self.fail("pause returned of its own accord, and the signal"
135 " didn't arrive after another second.")
Thomas Woutersed03b412007-08-28 21:37:11 +0000136
R. David Murray44546f82010-04-21 01:59:28 +0000137 # Issue 3864, unknown if this affects earlier versions of freebsd also
138 @unittest.skipIf(sys.platform=='freebsd6',
139 'inter process signals not reliable (do not mix well with threading) '
140 'on freebsd6')
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000141 def test_main(self):
142 # This function spawns a child process to insulate the main
143 # test-running process from all the signals. It then
144 # communicates with that child process over a pipe and
145 # re-raises information about any exceptions the child
146 # throws. The real work happens in self.run_test().
147 os_done_r, os_done_w = os.pipe()
Raymond Hettinger686057b2009-06-04 00:11:54 +0000148 with closing(os.fdopen(os_done_r, 'rb')) as done_r, \
149 closing(os.fdopen(os_done_w, 'wb')) as done_w:
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000150 child = os.fork()
151 if child == 0:
152 # In the child process; run the test and report results
153 # through the pipe.
154 try:
155 done_r.close()
156 # Have to close done_w again here because
157 # exit_subprocess() will skip the enclosing with block.
158 with closing(done_w):
159 try:
160 self.run_test()
161 except:
162 pickle.dump(traceback.format_exc(), done_w)
163 else:
164 pickle.dump(None, done_w)
165 except:
166 print('Uh oh, raised from pickle.')
167 traceback.print_exc()
168 finally:
169 exit_subprocess()
170
171 done_w.close()
172 # Block for up to MAX_DURATION seconds for the test to finish.
173 r, w, x = select.select([done_r], [], [], self.MAX_DURATION)
174 if done_r in r:
175 tb = pickle.load(done_r)
176 if tb:
177 self.fail(tb)
178 else:
179 os.kill(child, signal.SIGKILL)
180 self.fail('Test deadlocked after %d seconds.' %
181 self.MAX_DURATION)
Thomas Woutersed03b412007-08-28 21:37:11 +0000182
183
Brian Curtin3f004b12010-08-06 19:34:52 +0000184@unittest.skipIf(sys.platform == "win32", "Not valid on Windows")
Victor Stinnerb3e72192011-05-08 01:46:11 +0200185class PosixTests(unittest.TestCase):
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000186 def trivial_signal_handler(self, *args):
187 pass
188
Thomas Woutersed03b412007-08-28 21:37:11 +0000189 def test_out_of_range_signal_number_raises_error(self):
190 self.assertRaises(ValueError, signal.getsignal, 4242)
191
Thomas Woutersed03b412007-08-28 21:37:11 +0000192 self.assertRaises(ValueError, signal.signal, 4242,
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000193 self.trivial_signal_handler)
Thomas Woutersed03b412007-08-28 21:37:11 +0000194
195 def test_setting_signal_handler_to_none_raises_error(self):
196 self.assertRaises(TypeError, signal.signal,
197 signal.SIGUSR1, None)
198
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000199 def test_getsignal(self):
200 hup = signal.signal(signal.SIGHUP, self.trivial_signal_handler)
Ezio Melotti19f2aeb2010-11-21 01:30:29 +0000201 self.assertEqual(signal.getsignal(signal.SIGHUP),
202 self.trivial_signal_handler)
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000203 signal.signal(signal.SIGHUP, hup)
Ezio Melotti19f2aeb2010-11-21 01:30:29 +0000204 self.assertEqual(signal.getsignal(signal.SIGHUP), hup)
Christian Heimes4fbc72b2008-03-22 00:47:35 +0000205
206
Brian Curtin3f004b12010-08-06 19:34:52 +0000207@unittest.skipUnless(sys.platform == "win32", "Windows specific")
208class WindowsSignalTests(unittest.TestCase):
209 def test_issue9324(self):
Brian Curtineccd4d92010-10-01 15:09:53 +0000210 # Updated for issue #10003, adding SIGBREAK
Brian Curtin3f004b12010-08-06 19:34:52 +0000211 handler = lambda x, y: None
Brian Curtineccd4d92010-10-01 15:09:53 +0000212 for sig in (signal.SIGABRT, signal.SIGBREAK, signal.SIGFPE,
213 signal.SIGILL, signal.SIGINT, signal.SIGSEGV,
214 signal.SIGTERM):
215 # Set and then reset a handler for signals that work on windows
216 signal.signal(sig, signal.signal(sig, handler))
Brian Curtin3f004b12010-08-06 19:34:52 +0000217
218 with self.assertRaises(ValueError):
219 signal.signal(-1, handler)
Brian Curtin80cd4bf2010-08-07 03:52:38 +0000220
221 with self.assertRaises(ValueError):
222 signal.signal(7, handler)
Brian Curtin3f004b12010-08-06 19:34:52 +0000223
224
225@unittest.skipIf(sys.platform == "win32", "Not valid on Windows")
Christian Heimes5fb7c2a2007-12-24 08:52:31 +0000226class WakeupSignalTests(unittest.TestCase):
Victor Stinnerd554cdf2011-07-04 17:49:40 +0200227 def check_wakeup(self, test_body, *signals):
228 # use a subprocess to have only one thread
Victor Stinnere40b3aa2011-07-04 17:35:10 +0200229 code = """if 1:
230 import fcntl
231 import os
232 import signal
Victor Stinnerd554cdf2011-07-04 17:49:40 +0200233 import struct
Christian Heimes5fb7c2a2007-12-24 08:52:31 +0000234
Victor Stinnerd554cdf2011-07-04 17:49:40 +0200235 signals = {!r}
Victor Stinnerc13ef662011-05-25 02:35:58 +0200236
Victor Stinnere40b3aa2011-07-04 17:35:10 +0200237 def handler(signum, frame):
238 pass
239
Victor Stinnerd554cdf2011-07-04 17:49:40 +0200240 def check_signum(signals):
241 data = os.read(read, len(signals)+1)
242 raised = struct.unpack('%uB' % len(data), data)
243 # We don't care of the signal delivery order (it's not portable or
244 # reliable)
245 raised = set(raised)
246 signals = set(signals)
247 assert raised == signals, "%r != %r" % (raised, signals)
248
Victor Stinnere40b3aa2011-07-04 17:35:10 +0200249 {}
250
251 signal.signal(signal.SIGALRM, handler)
252 read, write = os.pipe()
Victor Stinnerd554cdf2011-07-04 17:49:40 +0200253 for fd in (read, write):
254 flags = fcntl.fcntl(fd, fcntl.F_GETFL, 0)
255 flags = flags | os.O_NONBLOCK
256 fcntl.fcntl(fd, fcntl.F_SETFL, flags)
Victor Stinnere40b3aa2011-07-04 17:35:10 +0200257 signal.set_wakeup_fd(write)
258
259 test()
Victor Stinnerd554cdf2011-07-04 17:49:40 +0200260 check_signum(signals)
Victor Stinnere40b3aa2011-07-04 17:35:10 +0200261
262 os.close(read)
263 os.close(write)
Victor Stinnerd554cdf2011-07-04 17:49:40 +0200264 """.format(signals, test_body)
Victor Stinnere40b3aa2011-07-04 17:35:10 +0200265
266 assert_python_ok('-c', code)
Victor Stinnerd49b1f12011-05-08 02:03:15 +0200267
Christian Heimes5fb7c2a2007-12-24 08:52:31 +0000268 def test_wakeup_fd_early(self):
Victor Stinnere40b3aa2011-07-04 17:35:10 +0200269 self.check_wakeup("""def test():
270 import select
271 import time
Christian Heimes5fb7c2a2007-12-24 08:52:31 +0000272
Victor Stinnere40b3aa2011-07-04 17:35:10 +0200273 TIMEOUT_FULL = 10
274 TIMEOUT_HALF = 5
275
276 signal.alarm(1)
277 before_time = time.time()
278 # We attempt to get a signal during the sleep,
279 # before select is called
280 time.sleep(TIMEOUT_FULL)
281 mid_time = time.time()
282 dt = mid_time - before_time
Victor Stinnerd554cdf2011-07-04 17:49:40 +0200283 assert dt < TIMEOUT_HALF, dt
Victor Stinnere40b3aa2011-07-04 17:35:10 +0200284 select.select([read], [], [], TIMEOUT_FULL)
285 after_time = time.time()
286 dt = after_time - mid_time
Victor Stinnerd554cdf2011-07-04 17:49:40 +0200287 assert dt < TIMEOUT_HALF, dt
288 """, signal.SIGALRM)
Christian Heimes5fb7c2a2007-12-24 08:52:31 +0000289
290 def test_wakeup_fd_during(self):
Victor Stinnere40b3aa2011-07-04 17:35:10 +0200291 self.check_wakeup("""def test():
292 import select
293 import time
Christian Heimes5fb7c2a2007-12-24 08:52:31 +0000294
Victor Stinnere40b3aa2011-07-04 17:35:10 +0200295 TIMEOUT_FULL = 10
296 TIMEOUT_HALF = 5
Christian Heimes5fb7c2a2007-12-24 08:52:31 +0000297
Victor Stinnere40b3aa2011-07-04 17:35:10 +0200298 signal.alarm(1)
299 before_time = time.time()
300 # We attempt to get a signal during the select call
301 try:
302 select.select([read], [], [], TIMEOUT_FULL)
303 except select.error:
304 pass
305 else:
306 raise Exception("select.error not raised")
307 after_time = time.time()
308 dt = after_time - before_time
Victor Stinnerd554cdf2011-07-04 17:49:40 +0200309 assert dt < TIMEOUT_HALF, dt
310 """, signal.SIGALRM)
Victor Stinnerd49b1f12011-05-08 02:03:15 +0200311
312 def test_signum(self):
Victor Stinnerd554cdf2011-07-04 17:49:40 +0200313 self.check_wakeup("""def test():
314 signal.signal(signal.SIGUSR1, handler)
315 os.kill(os.getpid(), signal.SIGUSR1)
316 os.kill(os.getpid(), signal.SIGALRM)
317 """, signal.SIGUSR1, signal.SIGALRM)
Christian Heimes5fb7c2a2007-12-24 08:52:31 +0000318
Victor Stinnerc13ef662011-05-25 02:35:58 +0200319 @unittest.skipUnless(hasattr(signal, 'pthread_sigmask'),
320 'need signal.pthread_sigmask()')
Victor Stinnerc13ef662011-05-25 02:35:58 +0200321 def test_pending(self):
Victor Stinnerd554cdf2011-07-04 17:49:40 +0200322 self.check_wakeup("""def test():
323 signum1 = signal.SIGUSR1
324 signum2 = signal.SIGUSR2
Victor Stinnerc13ef662011-05-25 02:35:58 +0200325
Victor Stinnerd554cdf2011-07-04 17:49:40 +0200326 signal.signal(signum1, handler)
327 signal.signal(signum2, handler)
Victor Stinnerc13ef662011-05-25 02:35:58 +0200328
Victor Stinnerd554cdf2011-07-04 17:49:40 +0200329 signal.pthread_sigmask(signal.SIG_BLOCK, (signum1, signum2))
330 os.kill(os.getpid(), signum1)
331 os.kill(os.getpid(), signum2)
332 # Unblocking the 2 signals calls the C signal handler twice
333 signal.pthread_sigmask(signal.SIG_UNBLOCK, (signum1, signum2))
334 """, signal.SIGUSR1, signal.SIGUSR2)
Victor Stinnerc13ef662011-05-25 02:35:58 +0200335
Christian Heimes5fb7c2a2007-12-24 08:52:31 +0000336
Brian Curtin3f004b12010-08-06 19:34:52 +0000337@unittest.skipIf(sys.platform == "win32", "Not valid on Windows")
Christian Heimes8640e742008-02-23 16:23:06 +0000338class SiginterruptTest(unittest.TestCase):
Jean-Paul Calderone9c39bc72010-05-09 03:25:16 +0000339
Victor Stinnerd6284962011-06-20 23:28:09 +0200340 def readpipe_interrupted(self, interrupt):
Jean-Paul Calderone9c39bc72010-05-09 03:25:16 +0000341 """Perform a read during which a signal will arrive. Return True if the
342 read is interrupted by the signal and raises an exception. Return False
343 if it returns normally.
344 """
Victor Stinnerd6284962011-06-20 23:28:09 +0200345 # use a subprocess to have only one thread, to have a timeout on the
346 # blocking read and to not touch signal handling in this process
347 code = """if 1:
348 import errno
349 import os
350 import signal
351 import sys
Jean-Paul Calderone9c39bc72010-05-09 03:25:16 +0000352
Victor Stinnerd6284962011-06-20 23:28:09 +0200353 interrupt = %r
354 r, w = os.pipe()
Christian Heimes8640e742008-02-23 16:23:06 +0000355
Victor Stinnerd6284962011-06-20 23:28:09 +0200356 def handler(signum, frame):
357 pass
358
359 signal.signal(signal.SIGALRM, handler)
360 if interrupt is not None:
361 signal.siginterrupt(signal.SIGALRM, interrupt)
362
Victor Stinnerdfde0d42011-07-01 15:58:39 +0200363 print("ready")
364 sys.stdout.flush()
365
Victor Stinnerd6284962011-06-20 23:28:09 +0200366 # run the test twice
367 for loop in range(2):
368 # send a SIGALRM in a second (during the read)
369 signal.alarm(1)
370 try:
371 # blocking call: read from a pipe without data
372 os.read(r, 1)
373 except OSError as err:
374 if err.errno != errno.EINTR:
375 raise
376 else:
377 sys.exit(2)
378 sys.exit(3)
379 """ % (interrupt,)
380 with spawn_python('-c', code) as process:
Christian Heimes8640e742008-02-23 16:23:06 +0000381 try:
Victor Stinner45273652011-06-22 22:15:51 +0200382 # wait until the child process is loaded and has started
383 first_line = process.stdout.readline()
384
Victor Stinner19e5bcd2011-07-01 15:59:54 +0200385 stdout, stderr = process.communicate(timeout=5.0)
Victor Stinnerd6284962011-06-20 23:28:09 +0200386 except subprocess.TimeoutExpired:
387 process.kill()
Christian Heimes8640e742008-02-23 16:23:06 +0000388 return False
Victor Stinnerd6284962011-06-20 23:28:09 +0200389 else:
Victor Stinner45273652011-06-22 22:15:51 +0200390 stdout = first_line + stdout
Victor Stinnerd6284962011-06-20 23:28:09 +0200391 exitcode = process.wait()
392 if exitcode not in (2, 3):
393 raise Exception("Child error (exit code %s): %s"
394 % (exitcode, stdout))
395 return (exitcode == 3)
Christian Heimes8640e742008-02-23 16:23:06 +0000396
397 def test_without_siginterrupt(self):
Victor Stinner3a7f0f02011-05-08 02:10:36 +0200398 # If a signal handler is installed and siginterrupt is not called
399 # at all, when that signal arrives, it interrupts a syscall that's in
400 # progress.
Victor Stinnerd6284962011-06-20 23:28:09 +0200401 interrupted = self.readpipe_interrupted(None)
402 self.assertTrue(interrupted)
Christian Heimes8640e742008-02-23 16:23:06 +0000403
404 def test_siginterrupt_on(self):
Victor Stinner3a7f0f02011-05-08 02:10:36 +0200405 # If a signal handler is installed and siginterrupt is called with
406 # a true value for the second argument, when that signal arrives, it
407 # interrupts a syscall that's in progress.
Victor Stinnerd6284962011-06-20 23:28:09 +0200408 interrupted = self.readpipe_interrupted(True)
409 self.assertTrue(interrupted)
Christian Heimes8640e742008-02-23 16:23:06 +0000410
411 def test_siginterrupt_off(self):
Victor Stinner3a7f0f02011-05-08 02:10:36 +0200412 # If a signal handler is installed and siginterrupt is called with
413 # a false value for the second argument, when that signal arrives, it
414 # does not interrupt a syscall that's in progress.
Victor Stinnerd6284962011-06-20 23:28:09 +0200415 interrupted = self.readpipe_interrupted(False)
416 self.assertFalse(interrupted)
Jean-Paul Calderone9c39bc72010-05-09 03:25:16 +0000417
418
Brian Curtin3f004b12010-08-06 19:34:52 +0000419@unittest.skipIf(sys.platform == "win32", "Not valid on Windows")
Martin v. Löwis823725e2008-03-24 13:39:54 +0000420class ItimerTest(unittest.TestCase):
421 def setUp(self):
422 self.hndl_called = False
423 self.hndl_count = 0
424 self.itimer = None
Christian Heimescc47b052008-03-25 14:56:36 +0000425 self.old_alarm = signal.signal(signal.SIGALRM, self.sig_alrm)
Martin v. Löwis823725e2008-03-24 13:39:54 +0000426
427 def tearDown(self):
Christian Heimescc47b052008-03-25 14:56:36 +0000428 signal.signal(signal.SIGALRM, self.old_alarm)
Martin v. Löwis823725e2008-03-24 13:39:54 +0000429 if self.itimer is not None: # test_itimer_exc doesn't change this attr
430 # just ensure that itimer is stopped
431 signal.setitimer(self.itimer, 0)
432
433 def sig_alrm(self, *args):
434 self.hndl_called = True
Martin v. Löwis823725e2008-03-24 13:39:54 +0000435
436 def sig_vtalrm(self, *args):
437 self.hndl_called = True
438
439 if self.hndl_count > 3:
440 # it shouldn't be here, because it should have been disabled.
441 raise signal.ItimerError("setitimer didn't disable ITIMER_VIRTUAL "
442 "timer.")
443 elif self.hndl_count == 3:
444 # disable ITIMER_VIRTUAL, this function shouldn't be called anymore
445 signal.setitimer(signal.ITIMER_VIRTUAL, 0)
Martin v. Löwis823725e2008-03-24 13:39:54 +0000446
447 self.hndl_count += 1
448
Martin v. Löwis823725e2008-03-24 13:39:54 +0000449 def sig_prof(self, *args):
450 self.hndl_called = True
451 signal.setitimer(signal.ITIMER_PROF, 0)
452
Martin v. Löwis823725e2008-03-24 13:39:54 +0000453 def test_itimer_exc(self):
454 # XXX I'm assuming -1 is an invalid itimer, but maybe some platform
455 # defines it ?
456 self.assertRaises(signal.ItimerError, signal.setitimer, -1, 0)
Christian Heimescc47b052008-03-25 14:56:36 +0000457 # Negative times are treated as zero on some platforms.
458 if 0:
459 self.assertRaises(signal.ItimerError,
460 signal.setitimer, signal.ITIMER_REAL, -1)
Martin v. Löwis823725e2008-03-24 13:39:54 +0000461
462 def test_itimer_real(self):
463 self.itimer = signal.ITIMER_REAL
Martin v. Löwis823725e2008-03-24 13:39:54 +0000464 signal.setitimer(self.itimer, 1.0)
Martin v. Löwis823725e2008-03-24 13:39:54 +0000465 signal.pause()
Martin v. Löwis823725e2008-03-24 13:39:54 +0000466 self.assertEqual(self.hndl_called, True)
467
R. David Murray44546f82010-04-21 01:59:28 +0000468 # Issue 3864, unknown if this affects earlier versions of freebsd also
Gregory P. Smith397cd8a2010-10-17 04:23:21 +0000469 @unittest.skipIf(sys.platform in ('freebsd6', 'netbsd5'),
470 'itimer not reliable (does not mix well with threading) on some BSDs.')
Martin v. Löwis823725e2008-03-24 13:39:54 +0000471 def test_itimer_virtual(self):
472 self.itimer = signal.ITIMER_VIRTUAL
473 signal.signal(signal.SIGVTALRM, self.sig_vtalrm)
474 signal.setitimer(self.itimer, 0.3, 0.2)
475
Mark Dickinson78373472009-10-31 10:39:21 +0000476 start_time = time.time()
Stefan Krahf1da973042010-04-20 08:15:14 +0000477 while time.time() - start_time < 60.0:
Mark Dickinson95078872009-10-04 18:47:48 +0000478 # use up some virtual time by doing real work
479 _ = pow(12345, 67890, 10000019)
Martin v. Löwis823725e2008-03-24 13:39:54 +0000480 if signal.getitimer(self.itimer) == (0.0, 0.0):
481 break # sig_vtalrm handler stopped this itimer
Stefan Krahf1da973042010-04-20 08:15:14 +0000482 else: # Issue 8424
Benjamin Peterson9b140f62010-05-15 18:00:56 +0000483 self.skipTest("timeout: likely cause: machine too slow or load too "
484 "high")
Martin v. Löwis823725e2008-03-24 13:39:54 +0000485
486 # virtual itimer should be (0.0, 0.0) now
Ezio Melotti19f2aeb2010-11-21 01:30:29 +0000487 self.assertEqual(signal.getitimer(self.itimer), (0.0, 0.0))
Martin v. Löwis823725e2008-03-24 13:39:54 +0000488 # and the handler should have been called
Ezio Melotti19f2aeb2010-11-21 01:30:29 +0000489 self.assertEqual(self.hndl_called, True)
Martin v. Löwis823725e2008-03-24 13:39:54 +0000490
R. David Murray44546f82010-04-21 01:59:28 +0000491 # Issue 3864, unknown if this affects earlier versions of freebsd also
492 @unittest.skipIf(sys.platform=='freebsd6',
493 'itimer not reliable (does not mix well with threading) on freebsd6')
Martin v. Löwis823725e2008-03-24 13:39:54 +0000494 def test_itimer_prof(self):
495 self.itimer = signal.ITIMER_PROF
496 signal.signal(signal.SIGPROF, self.sig_prof)
Neal Norwitzf5c7c2e2008-04-05 04:47:45 +0000497 signal.setitimer(self.itimer, 0.2, 0.2)
Martin v. Löwis823725e2008-03-24 13:39:54 +0000498
Mark Dickinson78373472009-10-31 10:39:21 +0000499 start_time = time.time()
Stefan Krahf1da973042010-04-20 08:15:14 +0000500 while time.time() - start_time < 60.0:
Mark Dickinson78373472009-10-31 10:39:21 +0000501 # do some work
502 _ = pow(12345, 67890, 10000019)
Martin v. Löwis823725e2008-03-24 13:39:54 +0000503 if signal.getitimer(self.itimer) == (0.0, 0.0):
504 break # sig_prof handler stopped this itimer
Stefan Krahf1da973042010-04-20 08:15:14 +0000505 else: # Issue 8424
Benjamin Peterson9b140f62010-05-15 18:00:56 +0000506 self.skipTest("timeout: likely cause: machine too slow or load too "
507 "high")
Martin v. Löwis823725e2008-03-24 13:39:54 +0000508
Neal Norwitzf5c7c2e2008-04-05 04:47:45 +0000509 # profiling itimer should be (0.0, 0.0) now
Ezio Melotti19f2aeb2010-11-21 01:30:29 +0000510 self.assertEqual(signal.getitimer(self.itimer), (0.0, 0.0))
Neal Norwitzf5c7c2e2008-04-05 04:47:45 +0000511 # and the handler should have been called
Martin v. Löwis823725e2008-03-24 13:39:54 +0000512 self.assertEqual(self.hndl_called, True)
513
Victor Stinnera9293352011-04-30 15:21:58 +0200514
Victor Stinner35b300c2011-05-04 13:20:35 +0200515class PendingSignalsTests(unittest.TestCase):
516 """
Victor Stinnerb3e72192011-05-08 01:46:11 +0200517 Test pthread_sigmask(), pthread_kill(), sigpending() and sigwait()
518 functions.
Victor Stinner35b300c2011-05-04 13:20:35 +0200519 """
Victor Stinnerb3e72192011-05-08 01:46:11 +0200520 @unittest.skipUnless(hasattr(signal, 'sigpending'),
521 'need signal.sigpending()')
522 def test_sigpending_empty(self):
523 self.assertEqual(signal.sigpending(), set())
524
525 @unittest.skipUnless(hasattr(signal, 'pthread_sigmask'),
526 'need signal.pthread_sigmask()')
527 @unittest.skipUnless(hasattr(signal, 'sigpending'),
528 'need signal.sigpending()')
529 def test_sigpending(self):
Victor Stinnerd554cdf2011-07-04 17:49:40 +0200530 code = """if 1:
531 import os
532 import signal
Victor Stinnerb3e72192011-05-08 01:46:11 +0200533
Victor Stinnerd554cdf2011-07-04 17:49:40 +0200534 def handler(signum, frame):
535 1/0
Victor Stinnerb3e72192011-05-08 01:46:11 +0200536
Victor Stinnerd554cdf2011-07-04 17:49:40 +0200537 signum = signal.SIGUSR1
538 signal.signal(signum, handler)
539
540 signal.pthread_sigmask(signal.SIG_BLOCK, [signum])
541 os.kill(os.getpid(), signum)
542 pending = signal.sigpending()
543 assert pending == {signum}, '%s != {%s}' % (pending, signum)
544 try:
545 signal.pthread_sigmask(signal.SIG_UNBLOCK, [signum])
546 except ZeroDivisionError:
547 pass
548 else:
549 raise Exception("ZeroDivisionError not raised")
550 """
551 assert_python_ok('-c', code)
Victor Stinnerb3e72192011-05-08 01:46:11 +0200552
553 @unittest.skipUnless(hasattr(signal, 'pthread_kill'),
554 'need signal.pthread_kill()')
555 def test_pthread_kill(self):
Victor Stinnerd554cdf2011-07-04 17:49:40 +0200556 code = """if 1:
557 import signal
558 import threading
559 import sys
Victor Stinnerb3e72192011-05-08 01:46:11 +0200560
Victor Stinnerd554cdf2011-07-04 17:49:40 +0200561 signum = signal.SIGUSR1
Victor Stinnerb3e72192011-05-08 01:46:11 +0200562
Victor Stinnerd554cdf2011-07-04 17:49:40 +0200563 def handler(signum, frame):
564 1/0
565
566 signal.signal(signum, handler)
567
568 if sys.platform == 'freebsd6':
569 # Issue #12392 and #12469: send a signal to the main thread
570 # doesn't work before the creation of the first thread on
571 # FreeBSD 6
572 def noop():
573 pass
574 thread = threading.Thread(target=noop)
575 thread.start()
576 thread.join()
577
578 tid = threading.get_ident()
579 try:
580 signal.pthread_kill(tid, signum)
581 except ZeroDivisionError:
582 pass
583 else:
584 raise Exception("ZeroDivisionError not raised")
585 """
586 assert_python_ok('-c', code)
Victor Stinnerb3e72192011-05-08 01:46:11 +0200587
Victor Stinner7f294d12011-06-10 14:02:10 +0200588 @unittest.skipUnless(hasattr(signal, 'pthread_sigmask'),
589 'need signal.pthread_sigmask()')
Victor Stinnerd554cdf2011-07-04 17:49:40 +0200590 def wait_helper(self, blocked, test):
Victor Stinner9e8b82f2011-06-29 10:43:02 +0200591 """
592 test: body of the "def test(signum):" function.
593 blocked: number of the blocked signal
594 """
Victor Stinnerd554cdf2011-07-04 17:49:40 +0200595 code = '''if 1:
596 import signal
597 import sys
Victor Stinner9e8b82f2011-06-29 10:43:02 +0200598
Victor Stinnerd554cdf2011-07-04 17:49:40 +0200599 def handler(signum, frame):
600 1/0
Victor Stinner9e8b82f2011-06-29 10:43:02 +0200601
Victor Stinnerd554cdf2011-07-04 17:49:40 +0200602 %s
Victor Stinner9e8b82f2011-06-29 10:43:02 +0200603
Victor Stinnerd554cdf2011-07-04 17:49:40 +0200604 blocked = %s
605 signum = signal.SIGALRM
Victor Stinner9e8b82f2011-06-29 10:43:02 +0200606
Victor Stinnerd554cdf2011-07-04 17:49:40 +0200607 # child: block and wait the signal
608 try:
609 signal.signal(signum, handler)
610 signal.pthread_sigmask(signal.SIG_BLOCK, [blocked])
Victor Stinner9e8b82f2011-06-29 10:43:02 +0200611
Victor Stinnerd554cdf2011-07-04 17:49:40 +0200612 # Do the tests
613 test(signum)
Victor Stinner9e8b82f2011-06-29 10:43:02 +0200614
Victor Stinnerd554cdf2011-07-04 17:49:40 +0200615 # The handler must not be called on unblock
616 try:
617 signal.pthread_sigmask(signal.SIG_UNBLOCK, [blocked])
618 except ZeroDivisionError:
619 print("the signal handler has been called",
620 file=sys.stderr)
621 sys.exit(1)
622 except BaseException as err:
623 print("error: {}".format(err), file=sys.stderr)
624 sys.stderr.flush()
625 sys.exit(1)
626 ''' % (test.strip(), blocked)
Victor Stinner415007e2011-06-13 16:19:06 +0200627
Ross Lagerwallbc808222011-06-25 12:13:40 +0200628 # sig*wait* must be called with the signal blocked: since the current
Victor Stinner9e8b82f2011-06-29 10:43:02 +0200629 # process might have several threads running, use a subprocess to have
630 # a single thread.
631 assert_python_ok('-c', code)
Victor Stinneraf494602011-06-10 12:48:13 +0200632
Victor Stinnerb3e72192011-05-08 01:46:11 +0200633 @unittest.skipUnless(hasattr(signal, 'sigwait'),
634 'need signal.sigwait()')
Ross Lagerwallbc808222011-06-25 12:13:40 +0200635 def test_sigwait(self):
Victor Stinnerd554cdf2011-07-04 17:49:40 +0200636 self.wait_helper(signal.SIGALRM, '''
637 def test(signum):
Ross Lagerwallbc808222011-06-25 12:13:40 +0200638 signal.alarm(1)
Victor Stinner9e8b82f2011-06-29 10:43:02 +0200639 received = signal.sigwait([signum])
640 assert received == signum , 'received %s, not %s' % (received, signum)
Victor Stinnerd554cdf2011-07-04 17:49:40 +0200641 ''')
Ross Lagerwallbc808222011-06-25 12:13:40 +0200642
643 @unittest.skipUnless(hasattr(signal, 'sigwaitinfo'),
644 'need signal.sigwaitinfo()')
645 def test_sigwaitinfo(self):
Victor Stinnerd554cdf2011-07-04 17:49:40 +0200646 self.wait_helper(signal.SIGALRM, '''
647 def test(signum):
Ross Lagerwallbc808222011-06-25 12:13:40 +0200648 signal.alarm(1)
649 info = signal.sigwaitinfo([signum])
Victor Stinner9e8b82f2011-06-29 10:43:02 +0200650 assert info.si_signo == signum, "info.si_signo != %s" % signum
Victor Stinnerd554cdf2011-07-04 17:49:40 +0200651 ''')
Ross Lagerwallbc808222011-06-25 12:13:40 +0200652
653 @unittest.skipUnless(hasattr(signal, 'sigtimedwait'),
654 'need signal.sigtimedwait()')
655 def test_sigtimedwait(self):
Victor Stinnerd554cdf2011-07-04 17:49:40 +0200656 self.wait_helper(signal.SIGALRM, '''
657 def test(signum):
Ross Lagerwallbc808222011-06-25 12:13:40 +0200658 signal.alarm(1)
659 info = signal.sigtimedwait([signum], (10, 1000))
Victor Stinner9e8b82f2011-06-29 10:43:02 +0200660 assert info.si_signo == signum, 'info.si_signo != %s' % signum
Victor Stinnerd554cdf2011-07-04 17:49:40 +0200661 ''')
Ross Lagerwallbc808222011-06-25 12:13:40 +0200662
Ross Lagerwallbc808222011-06-25 12:13:40 +0200663 @unittest.skipUnless(hasattr(signal, 'sigtimedwait'),
664 'need signal.sigtimedwait()')
Victor Stinner9e8b82f2011-06-29 10:43:02 +0200665 # issue #12303: sigtimedwait() takes 30 seconds on FreeBSD 6 (kernel bug)
666 @unittest.skipIf(sys.platform =='freebsd6',
Victor Stinnerd554cdf2011-07-04 17:49:40 +0200667 "sigtimedwait() with a null timeout doens't work on FreeBSD 6")
Ross Lagerwallbc808222011-06-25 12:13:40 +0200668 def test_sigtimedwait_poll(self):
Victor Stinner9e8b82f2011-06-29 10:43:02 +0200669 # check that polling with sigtimedwait works
Victor Stinnerd554cdf2011-07-04 17:49:40 +0200670 self.wait_helper(signal.SIGALRM, '''
671 def test(signum):
Victor Stinner9e8b82f2011-06-29 10:43:02 +0200672 import os
673 os.kill(os.getpid(), signum)
Ross Lagerwallbc808222011-06-25 12:13:40 +0200674 info = signal.sigtimedwait([signum], (0, 0))
Victor Stinner9e8b82f2011-06-29 10:43:02 +0200675 assert info.si_signo == signum, 'info.si_signo != %s' % signum
Victor Stinnerd554cdf2011-07-04 17:49:40 +0200676 ''')
Ross Lagerwallbc808222011-06-25 12:13:40 +0200677
678 @unittest.skipUnless(hasattr(signal, 'sigtimedwait'),
679 'need signal.sigtimedwait()')
680 def test_sigtimedwait_timeout(self):
Victor Stinnerd554cdf2011-07-04 17:49:40 +0200681 self.wait_helper(signal.SIGALRM, '''
682 def test(signum):
Victor Stinner9e8b82f2011-06-29 10:43:02 +0200683 received = signal.sigtimedwait([signum], (1, 0))
684 assert received is None, "received=%r" % (received,)
Victor Stinnerd554cdf2011-07-04 17:49:40 +0200685 ''')
Ross Lagerwallbc808222011-06-25 12:13:40 +0200686
687 @unittest.skipUnless(hasattr(signal, 'sigtimedwait'),
688 'need signal.sigtimedwait()')
689 def test_sigtimedwait_negative_timeout(self):
690 signum = signal.SIGALRM
691 self.assertRaises(ValueError, signal.sigtimedwait, [signum], (-1, -1))
692 self.assertRaises(ValueError, signal.sigtimedwait, [signum], (0, -1))
693 self.assertRaises(ValueError, signal.sigtimedwait, [signum], (-1, 0))
694
Ross Lagerwallbc808222011-06-25 12:13:40 +0200695 @unittest.skipUnless(hasattr(signal, 'sigwaitinfo'),
696 'need signal.sigwaitinfo()')
697 def test_sigwaitinfo_interrupted(self):
Victor Stinnerd554cdf2011-07-04 17:49:40 +0200698 self.wait_helper(signal.SIGUSR1, '''
699 def test(signum):
Victor Stinner9e8b82f2011-06-29 10:43:02 +0200700 import errno
701
702 hndl_called = True
703 def alarm_handler(signum, frame):
704 hndl_called = False
705
706 signal.signal(signal.SIGALRM, alarm_handler)
Ross Lagerwallbc808222011-06-25 12:13:40 +0200707 signal.alarm(1)
708 try:
709 signal.sigwaitinfo([signal.SIGUSR1])
710 except OSError as e:
711 if e.errno == errno.EINTR:
Victor Stinner9e8b82f2011-06-29 10:43:02 +0200712 assert hndl_called, "SIGALRM handler not called"
Ross Lagerwallbc808222011-06-25 12:13:40 +0200713 else:
Victor Stinner9e8b82f2011-06-29 10:43:02 +0200714 raise Exception("Expected EINTR to be raised by sigwaitinfo")
Ross Lagerwallbc808222011-06-25 12:13:40 +0200715 else:
Victor Stinner9e8b82f2011-06-29 10:43:02 +0200716 raise Exception("Expected EINTR to be raised by sigwaitinfo")
Victor Stinnerd554cdf2011-07-04 17:49:40 +0200717 ''')
Ross Lagerwallbc808222011-06-25 12:13:40 +0200718
719 @unittest.skipUnless(hasattr(signal, 'sigwait'),
720 'need signal.sigwait()')
Victor Stinner415007e2011-06-13 16:19:06 +0200721 @unittest.skipUnless(hasattr(signal, 'pthread_sigmask'),
722 'need signal.pthread_sigmask()')
Victor Stinner10c30d62011-06-10 01:39:53 +0200723 @unittest.skipIf(threading is None, "test needs threading module")
724 def test_sigwait_thread(self):
Victor Stinner415007e2011-06-13 16:19:06 +0200725 # Check that calling sigwait() from a thread doesn't suspend the whole
726 # process. A new interpreter is spawned to avoid problems when mixing
727 # threads and fork(): only async-safe functions are allowed between
728 # fork() and exec().
729 assert_python_ok("-c", """if True:
730 import os, threading, sys, time, signal
Victor Stinner10c30d62011-06-10 01:39:53 +0200731
Victor Stinner415007e2011-06-13 16:19:06 +0200732 # the default handler terminates the process
733 signum = signal.SIGUSR1
734
735 def kill_later():
736 # wait until the main thread is waiting in sigwait()
737 time.sleep(1)
738 os.kill(os.getpid(), signum)
739
740 # the signal must be blocked by all the threads
741 signal.pthread_sigmask(signal.SIG_BLOCK, [signum])
742 killer = threading.Thread(target=kill_later)
Victor Stinneraf494602011-06-10 12:48:13 +0200743 killer.start()
744 received = signal.sigwait([signum])
745 if received != signum:
746 print("sigwait() received %s, not %s" % (received, signum),
747 file=sys.stderr)
Victor Stinner415007e2011-06-13 16:19:06 +0200748 sys.exit(1)
Victor Stinner10c30d62011-06-10 01:39:53 +0200749 killer.join()
Victor Stinner415007e2011-06-13 16:19:06 +0200750 # unblock the signal, which should have been cleared by sigwait()
751 signal.pthread_sigmask(signal.SIG_UNBLOCK, [signum])
752 """)
Victor Stinneraf494602011-06-10 12:48:13 +0200753
Victor Stinnerb3e72192011-05-08 01:46:11 +0200754 @unittest.skipUnless(hasattr(signal, 'pthread_sigmask'),
755 'need signal.pthread_sigmask()')
756 def test_pthread_sigmask_arguments(self):
757 self.assertRaises(TypeError, signal.pthread_sigmask)
758 self.assertRaises(TypeError, signal.pthread_sigmask, 1)
759 self.assertRaises(TypeError, signal.pthread_sigmask, 1, 2, 3)
760 self.assertRaises(OSError, signal.pthread_sigmask, 1700, [])
761
762 @unittest.skipUnless(hasattr(signal, 'pthread_sigmask'),
763 'need signal.pthread_sigmask()')
764 def test_pthread_sigmask(self):
Victor Stinnerd554cdf2011-07-04 17:49:40 +0200765 code = """if 1:
766 import signal
767 import os; import threading
768
769 def handler(signum, frame):
770 1/0
771
772 def kill(signum):
773 os.kill(os.getpid(), signum)
774
775 def read_sigmask():
776 return signal.pthread_sigmask(signal.SIG_BLOCK, [])
777
Victor Stinnerb3e72192011-05-08 01:46:11 +0200778 signum = signal.SIGUSR1
Victor Stinner6fd49e12011-05-04 12:38:03 +0200779
Victor Stinnerd0e516d2011-05-03 14:57:12 +0200780 # Install our signal handler
Victor Stinnerd554cdf2011-07-04 17:49:40 +0200781 old_handler = signal.signal(signum, handler)
Victor Stinnera9293352011-04-30 15:21:58 +0200782
Victor Stinnerd0e516d2011-05-03 14:57:12 +0200783 # Unblock SIGUSR1 (and copy the old mask) to test our signal handler
Victor Stinnera9293352011-04-30 15:21:58 +0200784 old_mask = signal.pthread_sigmask(signal.SIG_UNBLOCK, [signum])
Victor Stinnerd554cdf2011-07-04 17:49:40 +0200785 try:
786 kill(signum)
787 except ZeroDivisionError:
788 pass
789 else:
790 raise Exception("ZeroDivisionError not raised")
Victor Stinnera9293352011-04-30 15:21:58 +0200791
Victor Stinnerd0e516d2011-05-03 14:57:12 +0200792 # Block and then raise SIGUSR1. The signal is blocked: the signal
793 # handler is not called, and the signal is now pending
Victor Stinnera9293352011-04-30 15:21:58 +0200794 signal.pthread_sigmask(signal.SIG_BLOCK, [signum])
Victor Stinnerd554cdf2011-07-04 17:49:40 +0200795 kill(signum)
Victor Stinnera9293352011-04-30 15:21:58 +0200796
Victor Stinnerd0e516d2011-05-03 14:57:12 +0200797 # Check the new mask
Victor Stinnerd554cdf2011-07-04 17:49:40 +0200798 blocked = read_sigmask()
799 assert signum in blocked, "%s not in %s" % (signum, blocked)
800 assert old_mask ^ blocked == {signum}, "%s ^ %s != {%s}" % (old_mask, blocked, signum)
Victor Stinnera9293352011-04-30 15:21:58 +0200801
Victor Stinnerd0e516d2011-05-03 14:57:12 +0200802 # Unblock SIGUSR1
Victor Stinnerd554cdf2011-07-04 17:49:40 +0200803 try:
804 # unblock the pending signal calls immediatly the signal handler
Victor Stinnerd0e516d2011-05-03 14:57:12 +0200805 signal.pthread_sigmask(signal.SIG_UNBLOCK, [signum])
Victor Stinnerd554cdf2011-07-04 17:49:40 +0200806 except ZeroDivisionError:
807 pass
808 else:
809 raise Exception("ZeroDivisionError not raised")
810 try:
811 kill(signum)
812 except ZeroDivisionError:
813 pass
814 else:
815 raise Exception("ZeroDivisionError not raised")
Victor Stinnera9293352011-04-30 15:21:58 +0200816
Victor Stinnerd0e516d2011-05-03 14:57:12 +0200817 # Check the new mask
Victor Stinnerd554cdf2011-07-04 17:49:40 +0200818 unblocked = read_sigmask()
819 assert signum not in unblocked, "%s in %s" % (signum, unblocked)
820 assert blocked ^ unblocked == {signum}, "%s ^ %s != {%s}" % (blocked, unblocked, signum)
821 assert old_mask == unblocked, "%s != %s" % (old_mask, unblocked)
822 """
823 assert_python_ok('-c', code)
824
825 @unittest.skipIf(sys.platform == 'freebsd6',
826 "issue #12392: send a signal to the main thread doesn't work "
827 "before the creation of the first thread on FreeBSD 6")
828 @unittest.skipUnless(hasattr(signal, 'pthread_kill'),
829 'need signal.pthread_kill()')
830 def test_pthread_kill_main_thread(self):
831 # Test that a signal can be sent to the main thread with pthread_kill()
832 # before any other thread has been created (see issue #12392).
833 code = """if True:
834 import threading
835 import signal
836 import sys
837
838 def handler(signum, frame):
839 sys.exit(3)
840
841 signal.signal(signal.SIGUSR1, handler)
842 signal.pthread_kill(threading.get_ident(), signal.SIGUSR1)
843 sys.exit(2)
844 """
845
846 with spawn_python('-c', code) as process:
847 stdout, stderr = process.communicate()
848 exitcode = process.wait()
849 if exitcode != 3:
850 raise Exception("Child error (exit code %s): %s" %
851 (exitcode, stdout))
Victor Stinnera9293352011-04-30 15:21:58 +0200852
853
Thomas Woutersed03b412007-08-28 21:37:11 +0000854def test_main():
Antoine Pitrou8189ab82011-03-20 17:35:32 +0100855 try:
Victor Stinnerb3e72192011-05-08 01:46:11 +0200856 support.run_unittest(PosixTests, InterProcessSignalTests,
Antoine Pitrou8189ab82011-03-20 17:35:32 +0100857 WakeupSignalTests, SiginterruptTest,
Victor Stinnera9293352011-04-30 15:21:58 +0200858 ItimerTest, WindowsSignalTests,
Victor Stinner35b300c2011-05-04 13:20:35 +0200859 PendingSignalsTests)
Antoine Pitrou8189ab82011-03-20 17:35:32 +0100860 finally:
861 support.reap_children()
Thomas Woutersed03b412007-08-28 21:37:11 +0000862
863
864if __name__ == "__main__":
865 test_main()