This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: BSD restartable signals not correctly disabled
Type: Stage:
Components: Interpreter Core Versions:
process
Status: closed Resolution: fixed
Dependencies: Superseder:
Assigned To: anthonybaxter Nosy List: anthonybaxter, lukem
Priority: normal Keywords:

Created on 2004-06-09 12:59 by lukem, last changed 2022-04-11 14:56 by admin. This issue is now closed.

Files
File name Uploaded Description Edit
python.fix lukem, 2004-06-09 13:00 restartablesignal.patch
Messages (3)
msg21096 - (view) Author: Luke Mewburn (lukem) Date: 2004-06-09 12:59
I noticed a problem with some python scripts not
performing correctly when ^C (SIGINT) was pressed. I
managed to isolate it to the following test case:
    import sys
    foo=sys.stdin.read()

Once that's executed, you need to press ^C _twice_ for
KeyboardInterrupt to be raised; the first ^C is
ignored.  If you manually enter that into an
interactive python session this behaviour also occurs,
although it appears to function correctly if you run
the foo=sys.stdin.read() a second time (only  one ^C is
needed).

This occurs on NetBSD 1.6 and 2.0, with python 2.1, 2.2
and 2.3, configured with and without pthreads.  It also
occurs on FreeBSD 4.8 with python 2.2.2.  It does not
occur on various Linux systems I asked people to test
for me.

(I have a NetBSD problem report about this issue:
http://www.netbsd.org/cgi-bin/query-pr-single.pl?number=24797
)

I traced the process and noticed that the read() system
call was being restarted when the first SIGINT was
received.  This hint, and the fact that Linux was
unaffected indicated that python was probably not
expecting restartable signal behaviour, and that
behaviour is the default in BSD systems for signal(3)
(but not sigaction(2) or the other POSIX signal calls).

After doing some research in the python 2.3.4 source it
appeared to me that the intent was to disable
restartable signals, but that was not what was
happening in practice.  I noticed the following code
issues:
  * not all code had been converted from using
signal(3) to PyOS_getsig() and PyOS_setsig().  This is
contrary to the HISTORY for python 2.0beta2.
  * siginterrupt(2) (an older BSD function) was being
used in places in an attempt to ensure that signals
were not restartable.  However, in some cases this
function was called _before_ signal(3)/PyOS_setsig(),
which would mean that the call may be ineffective if
PyOS_setsig() was implemented using signal(3) and not
sigaction(2)
   * PyOS_setsig() was using sigaction(2) suboptimally,
iand inheriting the sa_flags from the existing handler.
 If SA_RESTART happened to be already set for the
signal, it would be copied.

I provide the following patch, which does:
  * converts a few remaining signal(3) calls to
PyOS_setsig().  There should be none left in a build on
a UNIX system, although there may be on other systems.
 Converting any remaining calls to signal(3) is left as
an exercise :)
  * moves siginterrupt(2) to PyOS_setsig() when the
latter is implemented using signal(3) instead of
sigaction(2).
  * when implementing PyOS_setsig() in terms of
sigaction(2), use sigaction(2) in a more portable and
"common" manner that explicitly clears the flags for
the new handler, thus preventing SA_RESTART from being
implicitly copied.

With this patch applied, python passes all the same
regression tests as without it, and my test case now
exits on the first ^C as expected.

Also, it is possible that this patch may also fix other
outstanding signal issues on systems with BSD
restartable signal semantics.

Cheers,
Luke.
msg21097 - (view) Author: Luke Mewburn (lukem) Date: 2004-06-18 00:06
Logged In: YES 
user_id=135998

I've submitted patch 975056 which has a more complete
version of the patch to fix this.
msg21098 - (view) Author: Anthony Baxter (anthonybaxter) (Python triager) Date: 2004-10-13 14:56
Logged In: YES 
user_id=29957

Patch applied. Thanks!
History
Date User Action Args
2022-04-11 14:56:04adminsetgithub: 40366
2004-06-09 12:59:59lukemcreate