diff options
Diffstat (limited to 'portage_with_autodep/pym/_emerge/EbuildBuildDir.py')
-rw-r--r-- | portage_with_autodep/pym/_emerge/EbuildBuildDir.py | 109 |
1 files changed, 109 insertions, 0 deletions
diff --git a/portage_with_autodep/pym/_emerge/EbuildBuildDir.py b/portage_with_autodep/pym/_emerge/EbuildBuildDir.py new file mode 100644 index 0000000..ddc5fe0 --- /dev/null +++ b/portage_with_autodep/pym/_emerge/EbuildBuildDir.py @@ -0,0 +1,109 @@ +# Copyright 1999-2011 Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 + +from _emerge.AsynchronousLock import AsynchronousLock +from _emerge.SlotObject import SlotObject +import portage +from portage import os +from portage.exception import PortageException +import errno + +class EbuildBuildDir(SlotObject): + + __slots__ = ("scheduler", "settings", + "locked", "_catdir", "_lock_obj") + + def __init__(self, **kwargs): + SlotObject.__init__(self, **kwargs) + self.locked = False + + def lock(self): + """ + This raises an AlreadyLocked exception if lock() is called + while a lock is already held. In order to avoid this, call + unlock() or check whether the "locked" attribute is True + or False before calling lock(). + """ + if self._lock_obj is not None: + raise self.AlreadyLocked((self._lock_obj,)) + + dir_path = self.settings.get('PORTAGE_BUILDDIR') + if not dir_path: + raise AssertionError('PORTAGE_BUILDDIR is unset') + catdir = os.path.dirname(dir_path) + self._catdir = catdir + + try: + portage.util.ensure_dirs(os.path.dirname(catdir), + gid=portage.portage_gid, + mode=0o70, mask=0) + except PortageException: + if not os.path.isdir(os.path.dirname(catdir)): + raise + catdir_lock = AsynchronousLock(path=catdir, scheduler=self.scheduler) + catdir_lock.start() + catdir_lock.wait() + self._assert_lock(catdir_lock) + + try: + try: + portage.util.ensure_dirs(catdir, + gid=portage.portage_gid, + mode=0o70, mask=0) + except PortageException: + if not os.path.isdir(catdir): + raise + builddir_lock = AsynchronousLock(path=dir_path, + scheduler=self.scheduler) + builddir_lock.start() + builddir_lock.wait() + self._assert_lock(builddir_lock) + self._lock_obj = builddir_lock + self.settings['PORTAGE_BUILDIR_LOCKED'] = '1' + finally: + self.locked = self._lock_obj is not None + catdir_lock.unlock() + + def _assert_lock(self, async_lock): + if async_lock.returncode != os.EX_OK: + # TODO: create a better way to propagate this error to the caller + raise AssertionError("AsynchronousLock failed with returncode %s" \ + % (async_lock.returncode,)) + + def clean_log(self): + """Discard existing log. The log will not be be discarded + in cases when it would not make sense, like when FEATURES=keepwork + is enabled.""" + settings = self.settings + if 'keepwork' in settings.features: + return + log_file = settings.get('PORTAGE_LOG_FILE') + if log_file is not None and os.path.isfile(log_file): + try: + os.unlink(log_file) + except OSError: + pass + + def unlock(self): + if self._lock_obj is None: + return + + self._lock_obj.unlock() + self._lock_obj = None + self.locked = False + self.settings.pop('PORTAGE_BUILDIR_LOCKED', None) + catdir_lock = AsynchronousLock(path=self._catdir, scheduler=self.scheduler) + catdir_lock.start() + if catdir_lock.wait() == os.EX_OK: + try: + os.rmdir(self._catdir) + except OSError as e: + if e.errno not in (errno.ENOENT, + errno.ENOTEMPTY, errno.EEXIST, errno.EPERM): + raise + finally: + catdir_lock.unlock() + + class AlreadyLocked(portage.exception.PortageException): + pass + |