summaryrefslogtreecommitdiffstats
path: root/Lib/asyncio/unix_events.py
diff options
context:
space:
mode:
Diffstat (limited to 'Lib/asyncio/unix_events.py')
-rw-r--r--Lib/asyncio/unix_events.py61
1 files changed, 45 insertions, 16 deletions
diff --git a/Lib/asyncio/unix_events.py b/Lib/asyncio/unix_events.py
index 7747ff4..f7f9eb2 100644
--- a/Lib/asyncio/unix_events.py
+++ b/Lib/asyncio/unix_events.py
@@ -177,7 +177,7 @@ class _UnixSelectorEventLoop(selector_events.BaseSelectorEventLoop):
stdin, stdout, stderr, bufsize,
extra=None, **kwargs):
with events.get_child_watcher() as watcher:
- waiter = futures.Future(loop=self)
+ waiter = self.create_future()
transp = _UnixSubprocessTransport(self, protocol, args, shell,
stdin, stdout, stderr, bufsize,
waiter=waiter, extra=extra,
@@ -305,14 +305,20 @@ class _UnixReadPipeTransport(transports.ReadTransport):
self._loop = loop
self._pipe = pipe
self._fileno = pipe.fileno()
+ self._protocol = protocol
+ self._closing = False
+
mode = os.fstat(self._fileno).st_mode
if not (stat.S_ISFIFO(mode) or
stat.S_ISSOCK(mode) or
stat.S_ISCHR(mode)):
+ self._pipe = None
+ self._fileno = None
+ self._protocol = None
raise ValueError("Pipe transport is for pipes/sockets only.")
+
_set_nonblocking(self._fileno)
- self._protocol = protocol
- self._closing = False
+
self._loop.call_soon(self._protocol.connection_made, self)
# only start reading when connection_made() has been called
self._loop.call_soon(self._loop.add_reader,
@@ -329,14 +335,17 @@ class _UnixReadPipeTransport(transports.ReadTransport):
elif self._closing:
info.append('closing')
info.append('fd=%s' % self._fileno)
- if self._pipe is not None:
+ selector = getattr(self._loop, '_selector', None)
+ if self._pipe is not None and selector is not None:
polling = selector_events._test_selector_event(
- self._loop._selector,
+ selector,
self._fileno, selectors.EVENT_READ)
if polling:
info.append('polling')
else:
info.append('idle')
+ elif self._pipe is not None:
+ info.append('open')
else:
info.append('closed')
return '<%s>' % ' '.join(info)
@@ -365,6 +374,12 @@ class _UnixReadPipeTransport(transports.ReadTransport):
def resume_reading(self):
self._loop.add_reader(self._fileno, self._read_ready)
+ def set_protocol(self, protocol):
+ self._protocol = protocol
+
+ def get_protocol(self):
+ return self._protocol
+
def is_closing(self):
return self._closing
@@ -418,25 +433,30 @@ class _UnixWritePipeTransport(transports._FlowControlMixin,
self._extra['pipe'] = pipe
self._pipe = pipe
self._fileno = pipe.fileno()
+ self._protocol = protocol
+ self._buffer = []
+ self._conn_lost = 0
+ self._closing = False # Set when close() or write_eof() called.
+
mode = os.fstat(self._fileno).st_mode
+ is_char = stat.S_ISCHR(mode)
+ is_fifo = stat.S_ISFIFO(mode)
is_socket = stat.S_ISSOCK(mode)
- if not (is_socket or
- stat.S_ISFIFO(mode) or
- stat.S_ISCHR(mode)):
+ if not (is_char or is_fifo or is_socket):
+ self._pipe = None
+ self._fileno = None
+ self._protocol = None
raise ValueError("Pipe transport is only for "
"pipes, sockets and character devices")
+
_set_nonblocking(self._fileno)
- self._protocol = protocol
- self._buffer = []
- self._conn_lost = 0
- self._closing = False # Set when close() or write_eof() called.
self._loop.call_soon(self._protocol.connection_made, self)
# On AIX, the reader trick (to be notified when the read end of the
# socket is closed) only works for sockets. On other platforms it
# works for pipes and sockets. (Exception: OS X 10.4? Issue #19294.)
- if is_socket or not sys.platform.startswith("aix"):
+ if is_socket or (is_fifo and not sys.platform.startswith("aix")):
# only start reading when connection_made() has been called
self._loop.call_soon(self._loop.add_reader,
self._fileno, self._read_ready)
@@ -453,9 +473,10 @@ class _UnixWritePipeTransport(transports._FlowControlMixin,
elif self._closing:
info.append('closing')
info.append('fd=%s' % self._fileno)
- if self._pipe is not None:
+ selector = getattr(self._loop, '_selector', None)
+ if self._pipe is not None and selector is not None:
polling = selector_events._test_selector_event(
- self._loop._selector,
+ selector,
self._fileno, selectors.EVENT_WRITE)
if polling:
info.append('polling')
@@ -464,6 +485,8 @@ class _UnixWritePipeTransport(transports._FlowControlMixin,
bufsize = self.get_write_buffer_size()
info.append('bufsize=%s' % bufsize)
+ elif self._pipe is not None:
+ info.append('open')
else:
info.append('closed')
return '<%s>' % ' '.join(info)
@@ -553,6 +576,12 @@ class _UnixWritePipeTransport(transports._FlowControlMixin,
self._loop.remove_reader(self._fileno)
self._loop.call_soon(self._call_connection_lost, None)
+ def set_protocol(self, protocol):
+ self._protocol = protocol
+
+ def get_protocol(self):
+ return self._protocol
+
def is_closing(self):
return self._closing
@@ -575,7 +604,7 @@ class _UnixWritePipeTransport(transports._FlowControlMixin,
def _fatal_error(self, exc, message='Fatal error on pipe transport'):
# should be called by exception handler only
- if isinstance(exc, (BrokenPipeError, ConnectionResetError)):
+ if isinstance(exc, base_events._FATAL_ERROR_IGNORE):
if self._loop.get_debug():
logger.debug("%r: %s", self, message, exc_info=True)
else: