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

connect_write_pipe doesn't work properly on fds that support bidirectional I/O #369

@ronf

Description

@ronf

The connect_read_pipe() and connect_write_pipe() functions claim to work on character devices, sockets, and pipes. However, _UnixWritePipeTransport assumes that a write pipe has closed if _read_ready() ever triggers on it. This won't work for TTYs that allow both input & output on the same file descriptor. I think the same problem will occur with sockets.

I've been able to reproduce this failure by passing in sys.stdout to connect_write_pipe() when it is not redirected and pointing at /dev/tty. In that case, any input on stdin immediately called the write pipe opened on stdout to close.

Here's code which illustrates this:

import asyncio
import logging
import sys

logging.basicConfig(level='DEBUG')

class Reader(asyncio.Protocol):
    def data_received(self, data):
        print('Got data:', data)

class Writer(asyncio.BaseProtocol):
    pass

async def run(loop):
    stdin_t, _ = await loop.connect_read_pipe(Reader, sys.stdin)
    stdout_t, _ = await loop.connect_write_pipe(Writer, sys.stdout)

loop = asyncio.get_event_loop()
loop.run_until_complete(run(loop))

When run with PYTHONASYNCIODEBUG=1, I see the following output:

DEBUG:asyncio:Using selector: KqueueSelector
DEBUG:asyncio:Read pipe 0 connected: (<_UnixReadPipeTransport fd=0 polling>, <__main__.Reader object at 0x103f62828>)
DEBUG:asyncio:Write pipe 1 connected: (<_UnixWritePipeTransport fd=1 idle bufsize=0>, <__main__.Writer object at 0x1046d9208>)
a    <--- Input provided here
INFO:asyncio:poll took 2221.794 ms: 2 events
Got data: b'a\n'
INFO:asyncio:<_UnixWritePipeTransport fd=1 idle bufsize=0> was closed by peer

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions