[issue11753] test_sendall_interrupted() of test_socket hangs on FreeBSD

Charles-Francois Natali report at bugs.python.org
Sun Apr 3 22:58:50 CEST 2011


Charles-Francois Natali <neologix at free.fr> added the comment:

This test assumes that send will necessarily return if interrupted by a signal, but the kernel can automatically restart the syscall when no data has been committed (instead of returning -1 with errno set to EINTR).
And, AFAIK, that's exactly what FreeBSD does, see http://www.freebsd.org/cgi/man.cgi?query=siginterrupt&apropos=0&sektion=0&manpath=FreeBSD+8.2-RELEASE&format=html :
"""
The siginterrupt() function is used to change the system call restart
     behavior when a system call is interrupted by the specified signal.  If
     the flag is false (0), then system calls will be restarted if they are
     interrupted by the specified signal and no data has been transferred yet.
     System call restart has been the default behavior since 4.2BSD, and is
     the default behaviour for signal(3) on FreeBSD.
"""

And http://www.gsp.com/cgi-bin/man.cgi?section=2&topic=sigaction :

"""
If a signal is caught during the system calls listed below, the call may be forced to terminate with the error EINTR, the call may return with a data transfer shorter than requested, or the call may be restarted. Restart of pending calls is requested by setting the SA_RESTART bit in sa_flags. The affected system calls include open(2), read(2), write(2), sendto(2), recvfrom(2), sendmsg(2) and recvmsg(2) on a communications channel or a slow device (such as a terminal, but not a regular file) and during a wait(2) or ioctl(2). However, calls that have already committed are not restarted, but instead return a partial success (for example, a short read count).
"""

So if the signal arrives while some data has been transferred, send will return with a partial write, but if the signal arrives before any data has been written, then you'll never see EINTR and remain stuck forever (unless SA_RESTART is unset).
Note that POSIX seems to require write to return with EINTR if interrupted before any data is written, see http://pubs.opengroup.org/onlinepubs/009695399/functions/write.html :

"""
If write() is interrupted by a signal before it writes any data, it shall return -1 with errno set to [EINTR].
"""

But send and sendto man pages don't require this behaviour.

----------
nosy: +neologix

_______________________________________
Python tracker <report at bugs.python.org>
<http://bugs.python.org/issue11753>
_______________________________________


More information about the Python-bugs-list mailing list