summaryrefslogtreecommitdiffstats
path: root/pym/_emerge
diff options
context:
space:
mode:
authorZac Medico <zmedico@gentoo.org>2011-12-16 13:56:03 -0800
committerZac Medico <zmedico@gentoo.org>2011-12-16 13:56:03 -0800
commit47247149a48d8b4267ad849ff10924e7b6a6f3e2 (patch)
tree1f3338f3f3fa395075f7edc1cefd4491fde08cc4 /pym/_emerge
parentd33a45eba7c2ee8dab019908593d213e9c727314 (diff)
downloadportage-47247149a48d8b4267ad849ff10924e7b6a6f3e2.tar.gz
portage-47247149a48d8b4267ad849ff10924e7b6a6f3e2.tar.bz2
portage-47247149a48d8b4267ad849ff10924e7b6a6f3e2.zip
test_poll: fix array test
Since SpawnProcess no longer uses array, add conditional array support to PipeReader and use that for tests.
Diffstat (limited to 'pym/_emerge')
-rw-r--r--pym/_emerge/AbstractPollTask.py49
-rw-r--r--pym/_emerge/PipeReader.py29
2 files changed, 76 insertions, 2 deletions
diff --git a/pym/_emerge/AbstractPollTask.py b/pym/_emerge/AbstractPollTask.py
index b3c0b2d16..83e6c7b9c 100644
--- a/pym/_emerge/AbstractPollTask.py
+++ b/pym/_emerge/AbstractPollTask.py
@@ -1,6 +1,7 @@
# Copyright 1999-2011 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
+import array
import errno
import logging
import os
@@ -21,6 +22,54 @@ class AbstractPollTask(AsynchronousTask):
def isAlive(self):
return bool(self._registered)
+ def _read_array(self, f, event):
+ """
+ NOTE: array.fromfile() is used here only for testing purposes,
+ because it has bugs in all known versions of Python (including
+ Python 2.7 and Python 3.2).
+
+ | POLLIN | RETURN
+ | BIT | VALUE
+ | ---------------------------------------------------
+ | 1 | Read self._bufsize into an instance of
+ | | array.array('B') and return it, ignoring
+ | | EOFError and IOError. An empty array
+ | | indicates EOF.
+ | ---------------------------------------------------
+ | 0 | None
+ """
+ buf = None
+ if event & PollConstants.POLLIN:
+ buf = array.array('B')
+ try:
+ buf.fromfile(f, self._bufsize)
+ except EOFError:
+ pass
+ except TypeError:
+ # Python 3.2:
+ # TypeError: read() didn't return bytes
+ pass
+ except IOError as e:
+ # EIO happens with pty on Linux after the
+ # slave end of the pty has been closed.
+ if e.errno == errno.EIO:
+ # EOF: return empty string of bytes
+ pass
+ elif e.errno == errno.EAGAIN:
+ # EAGAIN: return None
+ buf = None
+ else:
+ raise
+
+ if buf is not None:
+ try:
+ # Python >=3.2
+ buf = buf.tobytes()
+ except AttributeError:
+ buf = buf.tostring()
+
+ return buf
+
def _read_buf(self, fd, event):
"""
| POLLIN | RETURN
diff --git a/pym/_emerge/PipeReader.py b/pym/_emerge/PipeReader.py
index 9fedbff6f..b162fe5cc 100644
--- a/pym/_emerge/PipeReader.py
+++ b/pym/_emerge/PipeReader.py
@@ -15,16 +15,22 @@ class PipeReader(AbstractPollTask):
"""
__slots__ = ("input_files",) + \
- ("_read_data", "_reg_ids")
+ ("_read_data", "_reg_ids", "_use_array")
def _start(self):
self._reg_ids = set()
self._read_data = []
+
+ if self._use_array:
+ output_handler = self._array_output_handler
+ else:
+ output_handler = self._output_handler
+
for k, f in self.input_files.items():
fcntl.fcntl(f.fileno(), fcntl.F_SETFL,
fcntl.fcntl(f.fileno(), fcntl.F_GETFL) | os.O_NONBLOCK)
self._reg_ids.add(self.scheduler.register(f.fileno(),
- self._registered_events, self._output_handler))
+ self._registered_events, output_handler))
self._registered = True
def isAlive(self):
@@ -68,6 +74,25 @@ class PipeReader(AbstractPollTask):
self._unregister_if_appropriate(event)
+ def _array_output_handler(self, fd, event):
+
+ for f in self.input_files.values():
+ if f.fileno() == fd:
+ break
+
+ while True:
+ data = self._read_array(f, event)
+ if data is None:
+ break
+ if data:
+ self._read_data.append(data)
+ else:
+ self._unregister()
+ self.wait()
+ break
+
+ self._unregister_if_appropriate(event)
+
def _unregister(self):
"""
Unregister from the scheduler and close open files.