From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from lists.gentoo.org (pigeon.gentoo.org [208.92.234.80]) by finch.gentoo.org (Postfix) with ESMTP id 41F63138A1A for ; Mon, 5 Jan 2015 19:36:24 +0000 (UTC) Received: from pigeon.gentoo.org (localhost [127.0.0.1]) by pigeon.gentoo.org (Postfix) with SMTP id 1D92EE083B; Mon, 5 Jan 2015 19:36:23 +0000 (UTC) Received: from smtp.gentoo.org (smtp.gentoo.org [140.211.166.183]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by pigeon.gentoo.org (Postfix) with ESMTPS id AB0FBE083B for ; Mon, 5 Jan 2015 19:36:22 +0000 (UTC) Received: from oystercatcher.gentoo.org (oystercatcher.gentoo.org [148.251.78.52]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by smtp.gentoo.org (Postfix) with ESMTPS id 74E333406B9 for ; Mon, 5 Jan 2015 19:36:21 +0000 (UTC) Received: from localhost.localdomain (localhost [127.0.0.1]) by oystercatcher.gentoo.org (Postfix) with ESMTP id 22B6DEEF4 for ; Mon, 5 Jan 2015 19:36:20 +0000 (UTC) From: "Zac Medico" To: gentoo-commits@lists.gentoo.org Content-Transfer-Encoding: 8bit Content-type: text/plain; charset=UTF-8 Reply-To: gentoo-dev@lists.gentoo.org, "Zac Medico" Message-ID: <1420486308.b3bba4dc8f4f93adeaeaf662870bb00a09bb1de7.zmedico@gentoo> Subject: [gentoo-commits] proj/portage:master commit in: pym/_emerge/ X-VCS-Repository: proj/portage X-VCS-Files: pym/_emerge/AbstractPollTask.py X-VCS-Directories: pym/_emerge/ X-VCS-Committer: zmedico X-VCS-Committer-Name: Zac Medico X-VCS-Revision: b3bba4dc8f4f93adeaeaf662870bb00a09bb1de7 X-VCS-Branch: master Date: Mon, 5 Jan 2015 19:36:20 +0000 (UTC) Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: List-Id: Gentoo Linux mail X-BeenThere: gentoo-commits@lists.gentoo.org X-Archives-Salt: 0fb853bc-ea15-4b8a-9724-ce496fce4ece X-Archives-Hash: ac8344ef4afdc45581b8c414db8e1d0d commit: b3bba4dc8f4f93adeaeaf662870bb00a09bb1de7 Author: Zac Medico gentoo org> AuthorDate: Fri Dec 26 08:59:58 2014 +0000 Commit: Zac Medico gentoo org> CommitDate: Mon Jan 5 19:31:48 2015 +0000 URL: http://sources.gentoo.org/gitweb/?p=proj/portage.git;a=commit;h=b3bba4dc AbstractPollTask._read_buf: read regardless of event flags (531724) PipeReaderPtyTestCase shows that data may be lost unless we attempt to read data for every poll event, regardless of the event flags. Therefore, always read, regardless of the event flags. This is safe to do because all consumers of this API use non-blocking mode and properly handle EAGAIN (signaled when this method returns None). X-Gentoo-Bug: 531724 X-Gentoo-Bug-URL: https://bugs.gentoo.org/show_bug.cgi?id=531724 Acked-by: Alexander Berntsen gentoo.org> --- pym/_emerge/AbstractPollTask.py | 52 +++++++++++++++++++++++------------------ 1 file changed, 29 insertions(+), 23 deletions(-) diff --git a/pym/_emerge/AbstractPollTask.py b/pym/_emerge/AbstractPollTask.py index 3f6dd6c..0d38bd4 100644 --- a/pym/_emerge/AbstractPollTask.py +++ b/pym/_emerge/AbstractPollTask.py @@ -1,4 +1,4 @@ -# Copyright 1999-2012 Gentoo Foundation +# Copyright 1999-2015 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 import array @@ -78,33 +78,39 @@ class AbstractPollTask(AsynchronousTask): def _read_buf(self, fd, event): """ - | POLLIN | RETURN - | BIT | VALUE - | --------------------------------------------------- - | 1 | Read self._bufsize into a string of bytes, - | | handling EAGAIN and EIO. An empty string - | | of bytes indicates EOF. - | --------------------------------------------------- - | 0 | None + Read self._bufsize into a string of bytes, handling EAGAIN and + EIO. This will only call os.read() once, so the caller should + call this method in a loop until either None or an empty string + of bytes is returned. An empty string of bytes indicates EOF. + None indicates EAGAIN. + + NOTE: os.read() will be called regardless of the event flags, + since otherwise data may be lost (see bug #531724). + + @param fd: file descriptor (non-blocking mode required) + @type fd: int + @param event: poll event flags + @type event: int + @rtype: bytes or None + @return: A string of bytes, or None """ # NOTE: array.fromfile() is no longer used here because it has # bugs in all known versions of Python (including Python 2.7 # and Python 3.2). buf = None - if event & self.scheduler.IO_IN: - try: - buf = os.read(fd, self._bufsize) - except OSError 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 - buf = b'' - elif e.errno == errno.EAGAIN: - # EAGAIN: return None - buf = None - else: - raise + try: + buf = os.read(fd, self._bufsize) + except OSError 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 + buf = b'' + elif e.errno == errno.EAGAIN: + # EAGAIN: return None + buf = None + else: + raise return buf