@@ -520,6 +520,7 @@ class PendingSignalsTests(unittest.TestCase):
520520 functions.
521521 """
522522 def setUp (self ):
523+ self .hndl_called = False
523524 self .has_pthread_kill = hasattr (signal , 'pthread_kill' )
524525
525526 def handler (self , signum , frame ):
@@ -607,52 +608,118 @@ def test_pthread_kill(self):
607608 with self .assertRaises (ZeroDivisionError ):
608609 signal .pthread_kill (current , signum )
609610
610- @unittest .skipUnless (hasattr (signal , 'sigwait' ),
611- 'need signal.sigwait()' )
612611 @unittest .skipUnless (hasattr (signal , 'pthread_sigmask' ),
613612 'need signal.pthread_sigmask()' )
614613 @unittest .skipUnless (hasattr (os , 'fork' ), 'need os.fork()' )
615- def test_sigwait (self ):
616- def test (signum ):
617- signal .alarm (1 )
618- received = signal .sigwait ([signum ])
619- if received != signum :
620- print ("sigwait() received %s, not %s"
621- % (received , signum ),
622- file = sys .stderr )
623- os ._exit (1 )
624-
614+ def wait_helper (self , test , handler , blocked = signal .SIGALRM ):
625615 signum = signal .SIGALRM
626616
627- # sigwait must be called with the signal blocked: since the current
617+ # sig*wait* must be called with the signal blocked: since the current
628618 # process might have several threads running, we fork() a child process
629619 # to have a single thread.
630620 pid = os .fork ()
631621 if pid == 0 :
632622 # child: block and wait the signal
633623 try :
634- signal .signal (signum , self . handler )
635- signal .pthread_sigmask (signal .SIG_BLOCK , [signum ])
624+ signal .signal (signum , handler )
625+ signal .pthread_sigmask (signal .SIG_BLOCK , [blocked ])
636626
637627 # Do the tests
638628 test (signum )
639629
640630 # The handler must not be called on unblock
641631 try :
642- signal .pthread_sigmask (signal .SIG_UNBLOCK , [signum ])
632+ signal .pthread_sigmask (signal .SIG_UNBLOCK , [blocked ])
643633 except ZeroDivisionError :
644634 print ("the signal handler has been called" ,
645635 file = sys .stderr )
646636 os ._exit (1 )
647637 except BaseException as err :
648638 print ("error: {}" .format (err ), file = sys .stderr )
639+ sys .stderr .flush ()
649640 os ._exit (1 )
650641 else :
651642 os ._exit (0 )
652643 else :
653644 # parent: check that the child correcty received the signal
654645 self .assertEqual (os .waitpid (pid , 0 ), (pid , 0 ))
655646
647+ @unittest .skipUnless (hasattr (signal , 'sigwait' ),
648+ 'need signal.sigwait()' )
649+ def test_sigwait (self ):
650+ def test (signum ):
651+ signal .alarm (1 )
652+ self .assertEqual (signum , signal .sigwait ([signum ]))
653+
654+ self .wait_helper (test , self .handler )
655+
656+ @unittest .skipUnless (hasattr (signal , 'sigwaitinfo' ),
657+ 'need signal.sigwaitinfo()' )
658+ def test_sigwaitinfo (self ):
659+ def test (signum ):
660+ signal .alarm (1 )
661+ info = signal .sigwaitinfo ([signum ])
662+ self .assertEqual (signum , info .si_signo )
663+
664+ self .wait_helper (test , self .handler )
665+
666+ @unittest .skipUnless (hasattr (signal , 'sigtimedwait' ),
667+ 'need signal.sigtimedwait()' )
668+ def test_sigtimedwait (self ):
669+ def test (signum ):
670+ signal .alarm (1 )
671+ info = signal .sigtimedwait ([signum ], (10 , 1000 ))
672+ self .assertEqual (signum , info .si_signo )
673+
674+ self .wait_helper (test , self .handler )
675+
676+ # check that polling with sigtimedwait works
677+ @unittest .skipUnless (hasattr (signal , 'sigtimedwait' ),
678+ 'need signal.sigtimedwait()' )
679+ def test_sigtimedwait_poll (self ):
680+ def test (signum ):
681+ self .kill (signum )
682+ info = signal .sigtimedwait ([signum ], (0 , 0 ))
683+ self .assertEqual (signum , info .si_signo )
684+
685+ self .wait_helper (test , self .handler )
686+
687+ @unittest .skipUnless (hasattr (signal , 'sigtimedwait' ),
688+ 'need signal.sigtimedwait()' )
689+ def test_sigtimedwait_timeout (self ):
690+ def test (signum ):
691+ self .assertEqual (None , signal .sigtimedwait ([signum ], (1 , 35500 )))
692+
693+ self .wait_helper (test , self .handler )
694+
695+ @unittest .skipUnless (hasattr (signal , 'sigtimedwait' ),
696+ 'need signal.sigtimedwait()' )
697+ def test_sigtimedwait_negative_timeout (self ):
698+ signum = signal .SIGALRM
699+ self .assertRaises (ValueError , signal .sigtimedwait , [signum ], (- 1 , - 1 ))
700+ self .assertRaises (ValueError , signal .sigtimedwait , [signum ], (0 , - 1 ))
701+ self .assertRaises (ValueError , signal .sigtimedwait , [signum ], (- 1 , 0 ))
702+
703+ def alarm_handler (self , signum , frame ):
704+ self .hndl_called = True
705+
706+ @unittest .skipUnless (hasattr (signal , 'sigwaitinfo' ),
707+ 'need signal.sigwaitinfo()' )
708+ def test_sigwaitinfo_interrupted (self ):
709+ def test (signum ):
710+ signal .alarm (1 )
711+ try :
712+ signal .sigwaitinfo ([signal .SIGUSR1 ])
713+ except OSError as e :
714+ if e .errno == errno .EINTR :
715+ self .assertTrue (self .hndl_called )
716+ else :
717+ self .fail ("Expected EINTR to be raised by sigwaitinfo" )
718+ else :
719+ self .fail ("Expected EINTR to be raised by sigwaitinfo" )
720+
721+ self .wait_helper (test , self .alarm_handler , signal .SIGUSR1 )
722+
656723 @unittest .skipUnless (hasattr (signal , 'sigwait' ),
657724 'need signal.sigwait()' )
658725 @unittest .skipUnless (hasattr (signal , 'pthread_sigmask' ),
0 commit comments