diff options
author | Zac Medico <zmedico@gentoo.org> | 2010-09-09 21:51:37 -0700 |
---|---|---|
committer | Zac Medico <zmedico@gentoo.org> | 2010-09-09 21:51:37 -0700 |
commit | 26434ee1b77dbff8f1904dd12204a93e87c8b6d3 (patch) | |
tree | 859cc85575ca4e6e7a7d7711ec56ee96a8b1e5d9 | |
parent | Bug #336644 - Make EbuildIpcDaemon use AbstractPollTask._read_buf(), (diff) | |
download | portage-26434ee1b77dbff8f1904dd12204a93e87c8b6d3.tar.gz portage-26434ee1b77dbff8f1904dd12204a93e87c8b6d3.tar.bz2 portage-26434ee1b77dbff8f1904dd12204a93e87c8b6d3.zip |
Bug #336644 - Make ebuild-ipc.py use array.fromfile() to read pickles
in single atomic non-blocking read() calls, similar to how
AbstractPollTask._read_buf() does it. If the read fails, exit with
status 2 so that best_version() and has_version() can detect the
error and die when necessary.
-rwxr-xr-x | bin/ebuild-ipc.py | 54 | ||||
-rwxr-xr-x | bin/ebuild.sh | 15 |
2 files changed, 36 insertions, 33 deletions
diff --git a/bin/ebuild-ipc.py b/bin/ebuild-ipc.py index 13c062654..3869a3c49 100755 --- a/bin/ebuild-ipc.py +++ b/bin/ebuild-ipc.py @@ -5,6 +5,7 @@ # This is a helper which ebuild processes can use # to communicate with portage's main python process. +import array import logging import os import pickle @@ -34,6 +35,7 @@ portage._disable_legacy_globals() class EbuildIpc(object): _COMMUNICATE_TIMEOUT_SECONDS = 40 + _BUFSIZE = 4096 def __init__(self): self.fifo_dir = os.environ['PORTAGE_BUILDDIR'] @@ -82,31 +84,33 @@ class EbuildIpc(object): events = select.select([input_file], [], []) - # Read the whole pickle in a single read() call since - # this stream is in non-blocking mode and pickle.load() - # has been known to raise the following exception when - # reading from a non-blocking stream: - # - # File "/usr/lib64/python2.6/pickle.py", line 1370, in load - # return Unpickler(file).load() - # File "/usr/lib64/python2.6/pickle.py", line 858, in load - # dispatch[key](self) - # File "/usr/lib64/python2.6/pickle.py", line 1195, in load_setitem - # value = stack.pop() - # IndexError: pop from empty list - - pickle_str = input_file.read() - reply = pickle.loads(pickle_str) - output_file.close() - input_file.close() - - (out, err, rval) = reply - - if out: - portage.util.writemsg_stdout(out, noiselevel=-1) - - if err: - portage.util.writemsg(err, noiselevel=-1) + # Read the whole pickle in a single atomic read() call. + buf = array.array('B') + try: + buf.fromfile(input_file, self._BUFSIZE) + except EOFError as e: + #portage.util.writemsg("%s\n" % (e), noiselevel=-1) + pass + except IOError as e: + portage.util.writemsg("%s\n" % (e), noiselevel=-1) + + if buf: + + reply = pickle.loads(buf.tostring()) + output_file.close() + input_file.close() + + (out, err, rval) = reply + + if out: + portage.util.writemsg_stdout(out, noiselevel=-1) + + if err: + portage.util.writemsg(err, noiselevel=-1) + + else: + + rval = 2 return rval diff --git a/bin/ebuild.sh b/bin/ebuild.sh index cc3b4a142..a742eae62 100755 --- a/bin/ebuild.sh +++ b/bin/ebuild.sh @@ -180,13 +180,13 @@ has_version() { die "portageq calls (has_version calls portageq) are not allowed in the global scope" fi + local retval if [[ -n $PORTAGE_IPC_DAEMON ]] ; then "$PORTAGE_BIN_PATH"/ebuild-ipc has_version "$ROOT" "$1" - return $? + else + PYTHONPATH=${PORTAGE_PYM_PATH}${PYTHONPATH:+:}${PYTHONPATH} \ + "${PORTAGE_PYTHON:-/usr/bin/python}" "${PORTAGE_BIN_PATH}/portageq" has_version "${ROOT}" "$1" fi - - PYTHONPATH=${PORTAGE_PYM_PATH}${PYTHONPATH:+:}${PYTHONPATH} \ - "${PORTAGE_PYTHON:-/usr/bin/python}" "${PORTAGE_BIN_PATH}/portageq" has_version "${ROOT}" "$1" local retval=$? case "${retval}" in 0) @@ -225,11 +225,10 @@ best_version() { if [[ -n $PORTAGE_IPC_DAEMON ]] ; then "$PORTAGE_BIN_PATH"/ebuild-ipc best_version "$ROOT" "$1" - return $? + else + PYTHONPATH=${PORTAGE_PYM_PATH}${PYTHONPATH:+:}${PYTHONPATH} \ + "${PORTAGE_PYTHON:-/usr/bin/python}" "${PORTAGE_BIN_PATH}/portageq" 'best_version' "${ROOT}" "$1" fi - - PYTHONPATH=${PORTAGE_PYM_PATH}${PYTHONPATH:+:}${PYTHONPATH} \ - "${PORTAGE_PYTHON:-/usr/bin/python}" "${PORTAGE_BIN_PATH}/portageq" 'best_version' "${ROOT}" "$1" local retval=$? case "${retval}" in 0) |