-# Copyright 2010 Gentoo Foundation
+# Copyright 2010-2011 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
import errno
+import logging
import pickle
from portage import os
+from portage.localization import _
+from portage.util import writemsg_level
from _emerge.FifoIpcDaemon import FifoIpcDaemon
from _emerge.PollConstants import PollConstants
def _send_reply(self, reply):
# File streams are in unbuffered mode since we do atomic
- # read and write of whole pickles.
- output_file = open(self.output_fifo, 'wb', 0)
- output_file.write(pickle.dumps(reply))
- output_file.close()
+ # read and write of whole pickles. Use non-blocking mode so
+ # we don't hang if the client is killed before we can send
+ # the reply. We rely on the client opening the other side
+ # of this fifo before it sends its request, since otherwise
+ # we'd have a race condition with this open call raising
+ # ENXIO if the client hasn't opened the fifo yet.
+ try:
+ output_fd = os.open(self.output_fifo,
+ os.O_WRONLY | os.O_NONBLOCK)
+ try:
+ os.write(output_fd, pickle.dumps(reply))
+ finally:
+ os.close(output_fd)
+ except OSError as e:
+ # This probably means that the client has been killed,
+ # which causes open to fail with ENXIO.
+ writemsg_level(
+ "!!! EbuildIpcDaemon %s: %s\n" % \
+ (_('failed to send reply'), e),
+ level=logging.ERROR, noiselevel=-1)