# This is a helper which ebuild processes can use
# to communicate with portage's main python process.
+import logging
import os
import pickle
import select
import signal
import sys
+import time
def debug_signal(signum, frame):
import pdb
class EbuildIpc(object):
+ _COMMUNICATE_TIMEOUT_SECONDS = 40
+
def __init__(self):
self.fifo_dir = os.environ['PORTAGE_BUILDDIR']
self.ipc_in_fifo = os.path.join(self.fifo_dir, '.ipc_in')
self.ipc_lock_file = os.path.join(self.fifo_dir, '.ipc_lock')
def communicate(self, args):
+
# Make locks quiet since unintended locking messages displayed on
# stdout could corrupt the intended output of this program.
portage.locks._quiet = True
lock_obj = portage.locks.lockfile(self.ipc_lock_file, unlinkfile=True)
+ start_time = time.time()
+
try:
- return self._communicate(args)
+ signal.signal(signal.SIGALRM, portage.exception.AlarmSignal.signal_handler)
+ signal.alarm(self._COMMUNICATE_TIMEOUT_SECONDS)
+ returncode = self._communicate(args)
+ signal.alarm(0)
+ return returncode
+ except portage.exception.AlarmSignal:
+ time_elapsed = time.time() - start_time
+ portage.util.writemsg_level(
+ ('ebuild-ipc timed out after %d seconds\n') % \
+ (time_elapsed,),
+ level=logging.ERROR, noiselevel=-1)
+ return 1
finally:
+ signal.alarm(0)
portage.locks.unlockfile(lock_obj)
def _communicate(self, args):
from errno import EAGAIN as errno
"""Try again"""
+class TimeoutException(PortageException):
+ from errno import ETIME as errno
+
+class AlarmSignal(TimeoutException):
+ def __init__(self, value, signum=None, frame=None):
+ TimeoutException.__init__(self, value)
+ self.signum = signum
+ self.frame = frame
+
+ @classmethod
+ def signal_handler(cls, signum, frame):
+ raise AlarmSignal("alarm signal",
+ signum=signum, frame=frame)
+
class ReadOnlyFileSystem(PortageException):
"""Read-only file system"""