Skip to content
This repository has been archived by the owner on Nov 23, 2017. It is now read-only.

Don't select for read on character devices in _UnixWritePipeTransport #374

Merged
merged 3 commits into from Aug 30, 2016

Conversation

ronf
Copy link

@ronf ronf commented Jul 6, 2016

Here's a pull request designed to fix the issue reported in #369.

_UnixWritePipeTransport selects for read on write pipes to detect when
the remote end of the pipe is closed. This works for unidirectional FIFOs
and dedicated socket pairs where nothing is written to the read side of
the pair, but it can cause problems with devices or sockets where
bidirectional I/O is being done.

This commit changes _UnixWritePipeTransport to only select for read on
sockets and FIFOs (on OSes which support that), and not on character
devices. When connect_write_pipe() is used on those devices,
end-of-file will need to be detected using a read pipe which accepts
inputs from the device.

No change is made to how sockets are handled, so passing in a socket
used for bidirectional I/O to connect_write_pipe() is not supported.
Async I/O on sockets should be performed using functions like
BaseEventLoop.create_connection(). Socket pairs which are only
used for undirectional I/O can be used here, though.

_UnixWritePipeTransport selects for read on write pipes to detect when
the remote end of the pipe is closed. This works for unidirectional FIFOs
and dedicated socket pairs where nothing is written to the read side of
the pair, but it can cause problems with devices or sockets where
bidirectional I/O is being done.

This commit changes _UnixWritePipeTransport to only select for read on
sockets and FIFOs (on OSes which support that), and not on character
devices. When connect_write_pipe() is used on those devices,
end-of-file will need to be detected using a read pipe which accepts
inputs from the device.

No change is made to how sockets are handled, so passing in a socket
used for bidirectional I/O to connect_write_pipe() is not supported.
Async I/O on sockets should be performed using functions like
BaseEventLoop.create_connection(). Socket pairs which are only
used for undirectional I/O can be used here, though.
@1st1
Copy link
Member

1st1 commented Jul 6, 2016

I think we have a couple of tests for connect_write_pipe. Can we add more to test the edge case this PR solves?

@ronf
Copy link
Author

ronf commented Jul 7, 2016

The main thing that this change addresses is when the file object passed into connect_write_pipe() is a TTY object with both read & write happening on it. It looks like there are read & write pty tests already in test_events.py, but they don't specifically address the bidirectional I/O case. It should be possible to add another test for this, though. I'll see what I can put together.

If I get something working, should I just add it to this same pull request?

@ronf
Copy link
Author

ronf commented Jul 8, 2016

I've gone ahead and checked in a new unit test which exercises this change. Without the fix here, the unit test would fail, reporting that the write pipe had closed prematurely. With the fix, bidirectional I/O can be performed on PTY/TTY pair without an issue.

@ronf
Copy link
Author

ronf commented Jul 8, 2016

I don't think the failed test here has anything to do with this commit. It's testing socket code, and from looking at the test my guess is that it's a race condition related to random port assignment on the test system. It assumes that the random port that was selected won't be in use when it connects after closing the listener, but something else could have come along and re-opened that port in the interim.

While the Windows release of Python seems to include the 'tty' module,
attempting to import it fails with an error about not finding the
'termios' module. Since the tty tests here aren't run on Windows,
though, there's no need to import tty there. This commit makes the
import conditional on the platform.
@ronf
Copy link
Author

ronf commented Aug 26, 2016

Is there anything more I can do on this? I signed the Python Contributor Agreement tonight.

@asvetlov
Copy link

LGTM.
I'll merge it tomorrow if nobody object

@asvetlov asvetlov self-assigned this Aug 28, 2016
@asvetlov asvetlov merged commit a30934a into python:master Aug 30, 2016
@asvetlov
Copy link

Thanks, @ronf

@ronf
Copy link
Author

ronf commented Aug 30, 2016

My pleasure. Thanks for merging the fix!

@ronf ronf deleted the write_pipe_tty_fix branch August 30, 2016 21:21
ronf added a commit to ronf/asyncio that referenced this pull request Aug 31, 2016
…python#374)

* Don't select for read on character devices in _UnixWritePipeTransport

_UnixWritePipeTransport selects for read on write pipes to detect when
the remote end of the pipe is closed. This works for unidirectional FIFOs
and dedicated socket pairs where nothing is written to the read side of
the pair, but it can cause problems with devices or sockets where
bidirectional I/O is being done.

This commit changes _UnixWritePipeTransport to only select for read on
sockets and FIFOs (on OSes which support that), and not on character
devices. When connect_write_pipe() is used on those devices,
end-of-file will need to be detected using a read pipe which accepts
inputs from the device.

No change is made to how sockets are handled, so passing in a socket
used for bidirectional I/O to connect_write_pipe() is not supported.
Async I/O on sockets should be performed using functions like
BaseEventLoop.create_connection(). Socket pairs which are only
used for undirectional I/O can be used here, though.

* Add new unit test for bidirectional I/O on TTYs

* Don't import tty module on Windows

While the Windows release of Python seems to include the 'tty' module,
attempting to import it fails with an error about not finding the
'termios' module. Since the tty tests here aren't run on Windows,
though, there's no need to import tty there. This commit makes the
import conditional on the platform.
akheron pushed a commit to akheron/cpython that referenced this pull request Sep 1, 2016
akruis pushed a commit to akruis/cpython that referenced this pull request Oct 29, 2017
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants