# Copyright 2010-2013 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2

from __future__ import unicode_literals

__all__ = ['doebuild', 'doebuild_environment', 'spawn', 'spawnebuild']

import grp
import gzip
import errno
import io
from itertools import chain
import logging
import os as _os
import pwd
import re
import signal
import stat
import sys
import tempfile
from textwrap import wrap
import time
import warnings
import zlib

import portage
portage.proxy.lazyimport.lazyimport(globals(),
	'portage.package.ebuild.config:check_config_instance',
	'portage.package.ebuild.digestcheck:digestcheck',
	'portage.package.ebuild.digestgen:digestgen',
	'portage.package.ebuild.fetch:fetch',
	'portage.package.ebuild._ipc.QueryCommand:QueryCommand',
	'portage.dep._slot_operator:evaluate_slot_operator_equal_deps',
	'portage.package.ebuild._spawn_nofetch:spawn_nofetch',
	'portage.util._desktop_entry:validate_desktop_entry',
	'portage.util._async.SchedulerInterface:SchedulerInterface',
	'portage.util._eventloop.EventLoop:EventLoop',
	'portage.util._eventloop.global_event_loop:global_event_loop',
	'portage.util.ExtractKernelVersion:ExtractKernelVersion'
)

from portage import auxdbkeys, bsd_chflags, \
	eapi_is_supported, merge, os, selinux, shutil, \
	unmerge, _encodings, _os_merge, \
	_shell_quote, _unicode_decode, _unicode_encode
from portage.const import EBUILD_SH_ENV_FILE, EBUILD_SH_ENV_DIR, \
	EBUILD_SH_BINARY, INVALID_ENV_FILE, MISC_SH_BINARY
from portage.data import portage_gid, portage_uid, secpass, \
	uid, userpriv_groups
from portage.dbapi.porttree import _parse_uri_map
from portage.dep import Atom, check_required_use, \
	human_readable_required_use, paren_enclose, use_reduce
from portage.eapi import eapi_exports_KV, eapi_exports_merge_type, \
	eapi_exports_replace_vars, eapi_exports_REPOSITORY, \
	eapi_has_required_use, eapi_has_src_prepare_and_src_configure, \
	eapi_has_pkg_pretend, _get_eapi_attrs
from portage.elog import elog_process, _preload_elog_modules
from portage.elog.messages import eerror, eqawarn
from portage.exception import DigestException, FileNotFound, \
	IncorrectParameter, InvalidDependString, PermissionDenied, \
	UnsupportedAPIException
from portage.localization import _
from portage.output import colormap
from portage.package.ebuild.prepare_build_dirs import prepare_build_dirs
from portage.util import apply_recursive_permissions, \
	apply_secpass_permissions, noiselimit, normalize_path, \
	writemsg, writemsg_stdout, write_atomic
from portage.util.lafilefixer import rewrite_lafile	
from portage.versions import _pkgsplit
from _emerge.BinpkgEnvExtractor import BinpkgEnvExtractor
from _emerge.EbuildBuildDir import EbuildBuildDir
from _emerge.EbuildPhase import EbuildPhase
from _emerge.EbuildSpawnProcess import EbuildSpawnProcess
from _emerge.Package import Package
from _emerge.RootConfig import RootConfig

_unsandboxed_phases = frozenset([
	"clean", "cleanrm", "config",
	"help", "info", "postinst",
	"preinst", "pretend", "postrm",
	"prerm", "setup"
])

_phase_func_map = {
	"config": "pkg_config",
	"setup": "pkg_setup",
	"nofetch": "pkg_nofetch",
	"unpack": "src_unpack",
	"prepare": "src_prepare",
	"configure": "src_configure",
	"compile": "src_compile",
	"test": "src_test",
	"install": "src_install",
	"preinst": "pkg_preinst",
	"postinst": "pkg_postinst",
	"prerm": "pkg_prerm",
	"postrm": "pkg_postrm",
	"info": "pkg_info",
	"pretend": "pkg_pretend",
}

_vdb_use_conditional_keys = Package._dep_keys + \
	('LICENSE', 'PROPERTIES', 'PROVIDE', 'RESTRICT',)

def _doebuild_spawn(phase, settings, actionmap=None, **kwargs):
	"""
	All proper ebuild phases which execute ebuild.sh are spawned
	via this function. No exceptions.
	"""

	if phase in _unsandboxed_phases:
		kwargs['free'] = True

	if phase == 'depend':
		kwargs['droppriv'] = 'userpriv' in settings.features
		# It's not necessary to close_fds for this phase, since
		# it should not spawn any daemons, and close_fds is
		# best avoided since it can interact badly with some
		# garbage collectors (see _setup_pipes docstring).
		kwargs['close_fds'] = False

	if actionmap is not None and phase in actionmap:
		kwargs.update(actionmap[phase]["args"])
		cmd = actionmap[phase]["cmd"] % phase
	else:
		if phase == 'cleanrm':
			ebuild_sh_arg = 'clean'
		else:
			ebuild_sh_arg = phase

		cmd = "%s %s" % (_shell_quote(
			os.path.join(settings["PORTAGE_BIN_PATH"],
			os.path.basename(EBUILD_SH_BINARY))),
			ebuild_sh_arg)

	settings['EBUILD_PHASE'] = phase
	try:
		return spawn(cmd, settings, **portage._native_kwargs(kwargs))
	finally:
		settings.pop('EBUILD_PHASE', None)

def _spawn_phase(phase, settings, actionmap=None, **kwargs):
	if kwargs.get('returnpid'):
		return _doebuild_spawn(phase, settings, actionmap=actionmap, **kwargs)

	ebuild_phase = EbuildPhase(actionmap=actionmap, background=False,
		phase=phase, scheduler=SchedulerInterface(portage._internal_caller and
			global_event_loop() or EventLoop(main=False)),
		settings=settings)
	ebuild_phase.start()
	ebuild_phase.wait()
	return ebuild_phase.returncode

def _doebuild_path(settings, eapi=None):
	"""
	Generate the PATH variable.
	"""

	# Note: PORTAGE_BIN_PATH may differ from the global constant
	# when portage is reinstalling itself.
	portage_bin_path = settings["PORTAGE_BIN_PATH"]
	eprefix = settings["EPREFIX"]
	prerootpath = [x for x in settings.get("PREROOTPATH", "").split(":") if x]
	rootpath = [x for x in settings.get("ROOTPATH", "").split(":") if x]
	overrides = [x for x in settings.get(
		"__PORTAGE_TEST_PATH_OVERRIDE", "").split(":") if x]

	prefixes = []
	if eprefix:
		prefixes.append(eprefix)
	prefixes.append("/")

	path = overrides

	if eprefix and uid != 0 and "fakeroot" not in settings.features:
		path.append(os.path.join(portage_bin_path,
			"ebuild-helpers", "unprivileged"))

	if settings.get("USERLAND", "GNU") != "GNU":
		path.append(os.path.join(portage_bin_path, "ebuild-helpers", "bsd"))

	path.append(os.path.join(portage_bin_path, "ebuild-helpers"))
	path.extend(prerootpath)

	for prefix in prefixes:
		for x in ("usr/local/sbin", "usr/local/bin", "usr/sbin", "usr/bin", "sbin", "bin"):
			path.append(os.path.join(prefix, x))

	path.extend(rootpath)
	settings["PATH"] = ":".join(path)

def doebuild_environment(myebuild, mydo, myroot=None, settings=None,
	debug=False, use_cache=None, db=None):
	"""
	Create and store environment variable in the config instance
	that's passed in as the "settings" parameter. This will raise
	UnsupportedAPIException if the given ebuild has an unsupported
	EAPI. All EAPI dependent code comes last, so that essential
	variables like PORTAGE_BUILDDIR are still initialized even in
	cases when UnsupportedAPIException needs to be raised, which
	can be useful when uninstalling a package that has corrupt
	EAPI metadata.
	The myroot and use_cache parameters are unused.
	"""
	myroot = None
	use_cache = None

	if settings is None:
		raise TypeError("settings argument is required")

	if db is None:
		raise TypeError("db argument is required")

	mysettings = settings
	mydbapi = db
	ebuild_path = os.path.abspath(myebuild)
	pkg_dir     = os.path.dirname(ebuild_path)
	mytree = os.path.dirname(os.path.dirname(pkg_dir))
	mypv = os.path.basename(ebuild_path)[:-7]
	mysplit = _pkgsplit(mypv, eapi=mysettings.configdict["pkg"].get("EAPI"))
	if mysplit is None:
		raise IncorrectParameter(
			_("Invalid ebuild path: '%s'") % myebuild)

	if mysettings.mycpv is not None and \
		mysettings.configdict["pkg"].get("PF") == mypv and \
		"CATEGORY" in mysettings.configdict["pkg"]:
		# Assume that PF is enough to assume that we've got
		# the correct CATEGORY, though this is not really
		# a solid assumption since it's possible (though
		# unlikely) that two packages in different
		# categories have the same PF. Callers should call
		# setcpv or create a clean clone of a locked config
		# instance in order to ensure that this assumption
		# does not fail like in bug #408817.
		cat = mysettings.configdict["pkg"]["CATEGORY"]
		mycpv = mysettings.mycpv
	elif os.path.basename(pkg_dir) in (mysplit[0], mypv):
		# portdbapi or vardbapi
		cat = os.path.basename(os.path.dirname(pkg_dir))
		mycpv = cat + "/" + mypv
	else:
		raise AssertionError("unable to determine CATEGORY")

	# Make a backup of PORTAGE_TMPDIR prior to calling config.reset()
	# so that the caller can override it.
	tmpdir = mysettings["PORTAGE_TMPDIR"]

	if mydo == 'depend':
		if mycpv != mysettings.mycpv:
			# Don't pass in mydbapi here since the resulting aux_get
			# call would lead to infinite 'depend' phase recursion.
			mysettings.setcpv(mycpv)
	else:
		# If EAPI isn't in configdict["pkg"], it means that setcpv()
		# hasn't been called with the mydb argument, so we have to
		# call it here (portage code always calls setcpv properly,
		# but api consumers might not).
		if mycpv != mysettings.mycpv or \
			"EAPI" not in mysettings.configdict["pkg"]:
			# Reload env.d variables and reset any previous settings.
			mysettings.reload()
			mysettings.reset()
			mysettings.setcpv(mycpv, mydb=mydbapi)

	# config.reset() might have reverted a change made by the caller,
	# so restore it to its original value. Sandbox needs canonical
	# paths, so realpath it.
	mysettings["PORTAGE_TMPDIR"] = os.path.realpath(tmpdir)

	mysettings.pop("EBUILD_PHASE", None) # remove from backupenv
	mysettings["EBUILD_PHASE"] = mydo

	# Set requested Python interpreter for Portage helpers.
	mysettings['PORTAGE_PYTHON'] = portage._python_interpreter

	# This is used by assert_sigpipe_ok() that's used by the ebuild
	# unpack() helper. SIGPIPE is typically 13, but its better not
	# to assume that.
	mysettings['PORTAGE_SIGPIPE_STATUS'] = str(128 + signal.SIGPIPE)

	# We are disabling user-specific bashrc files.
	mysettings["BASH_ENV"] = INVALID_ENV_FILE

	if debug: # Otherwise it overrides emerge's settings.
		# We have no other way to set debug... debug can't be passed in
		# due to how it's coded... Don't overwrite this so we can use it.
		mysettings["PORTAGE_DEBUG"] = "1"

	mysettings["EBUILD"]   = ebuild_path
	mysettings["O"]        = pkg_dir
	mysettings.configdict["pkg"]["CATEGORY"] = cat
	mysettings["FILESDIR"] = pkg_dir+"/files"
	mysettings["PF"]       = mypv

	if hasattr(mydbapi, 'repositories'):
		repo = mydbapi.repositories.get_repo_for_location(mytree)
		mysettings['PORTDIR'] = repo.eclass_db.porttrees[0]
		mysettings['PORTDIR_OVERLAY'] = ' '.join(repo.eclass_db.porttrees[1:])
		mysettings.configdict["pkg"]["PORTAGE_REPO_NAME"] = repo.name

	mysettings["PORTDIR"] = os.path.realpath(mysettings["PORTDIR"])
	mysettings["DISTDIR"] = os.path.realpath(mysettings["DISTDIR"])
	mysettings["RPMDIR"]  = os.path.realpath(mysettings["RPMDIR"])

	mysettings["ECLASSDIR"]   = mysettings["PORTDIR"]+"/eclass"
	mysettings["SANDBOX_LOG"] = mycpv.replace("/", "_-_")

	mysettings["PROFILE_PATHS"] = "\n".join(mysettings.profiles)
	mysettings["P"]  = mysplit[0]+"-"+mysplit[1]
	mysettings["PN"] = mysplit[0]
	mysettings["PV"] = mysplit[1]
	mysettings["PR"] = mysplit[2]

	if noiselimit < 0:
		mysettings["PORTAGE_QUIET"] = "1"

	if mysplit[2] == "r0":
		mysettings["PVR"]=mysplit[1]
	else:
		mysettings["PVR"]=mysplit[1]+"-"+mysplit[2]

	# All temporary directories should be subdirectories of
	# $PORTAGE_TMPDIR/portage, since it's common for /tmp and /var/tmp
	# to be mounted with the "noexec" option (see bug #346899).
	mysettings["BUILD_PREFIX"] = mysettings["PORTAGE_TMPDIR"]+"/portage"
	mysettings["PKG_TMPDIR"]   = mysettings["BUILD_PREFIX"]+"/._unmerge_"

	# Package {pre,post}inst and {pre,post}rm may overlap, so they must have separate
	# locations in order to prevent interference.
	if mydo in ("unmerge", "prerm", "postrm", "cleanrm"):
		mysettings["PORTAGE_BUILDDIR"] = os.path.join(
			mysettings["PKG_TMPDIR"],
			mysettings["CATEGORY"], mysettings["PF"])
	else:
		mysettings["PORTAGE_BUILDDIR"] = os.path.join(
			mysettings["BUILD_PREFIX"],
			mysettings["CATEGORY"], mysettings["PF"])

	mysettings["HOME"] = os.path.join(mysettings["PORTAGE_BUILDDIR"], "homedir")
	mysettings["WORKDIR"] = os.path.join(mysettings["PORTAGE_BUILDDIR"], "work")
	mysettings["D"] = os.path.join(mysettings["PORTAGE_BUILDDIR"], "image") + os.sep
	mysettings["T"] = os.path.join(mysettings["PORTAGE_BUILDDIR"], "temp")

	# Prefix forward compatability
	eprefix_lstrip = mysettings["EPREFIX"].lstrip(os.sep)
	mysettings["ED"] = os.path.join(
		mysettings["D"], eprefix_lstrip).rstrip(os.sep) + os.sep

	mysettings["PORTAGE_BASHRC"] = os.path.join(
		mysettings["PORTAGE_CONFIGROOT"], EBUILD_SH_ENV_FILE)
	mysettings["PM_EBUILD_HOOK_DIR"] = os.path.join(
		mysettings["PORTAGE_CONFIGROOT"], EBUILD_SH_ENV_DIR)

	# Allow color.map to control colors associated with einfo, ewarn, etc...
	mysettings["PORTAGE_COLORMAP"] = colormap()

	if "COLUMNS" not in mysettings:
		# Set COLUMNS, in order to prevent unnecessary stty calls
		# inside the set_colors function of isolated-functions.sh.
		# We cache the result in os.environ, in order to avoid
		# multiple stty calls in cases when get_term_size() falls
		# back to stty due to a missing or broken curses module.
		columns = os.environ.get("COLUMNS")
		if columns is None:
			rows, columns = portage.output.get_term_size()
			if columns < 1:
				# Force a sane value for COLUMNS, so that tools
				# like ls don't complain (see bug #394091).
				columns = 80
			columns = str(columns)
			os.environ["COLUMNS"] = columns
		mysettings["COLUMNS"] = columns

	# EAPI is always known here, even for the "depend" phase, because
	# EbuildMetadataPhase gets it from _parse_eapi_ebuild_head().
	eapi = mysettings.configdict['pkg']['EAPI']
	_doebuild_path(mysettings, eapi=eapi)

	# All EAPI dependent code comes last, so that essential variables like
	# PATH and PORTAGE_BUILDDIR are still initialized even in cases when
	# UnsupportedAPIException needs to be raised, which can be useful
	# when uninstalling a package that has corrupt EAPI metadata.
	if not eapi_is_supported(eapi):
		raise UnsupportedAPIException(mycpv, eapi)

	if eapi_exports_REPOSITORY(eapi) and "PORTAGE_REPO_NAME" in mysettings.configdict["pkg"]:
		mysettings.configdict["pkg"]["REPOSITORY"] = mysettings.configdict["pkg"]["PORTAGE_REPO_NAME"]

	if mydo != "depend":
		if hasattr(mydbapi, "getFetchMap") and \
			("A" not in mysettings.configdict["pkg"] or \
			"AA" not in mysettings.configdict["pkg"]):
			src_uri, = mydbapi.aux_get(mysettings.mycpv,
				["SRC_URI"], mytree=mytree)
			metadata = {
				"EAPI"    : eapi,
				"SRC_URI" : src_uri,
			}
			use = frozenset(mysettings["PORTAGE_USE"].split())
			try:
				uri_map = _parse_uri_map(mysettings.mycpv, metadata, use=use)
			except InvalidDependString:
				mysettings.configdict["pkg"]["A"] = ""
			else:
				mysettings.configdict["pkg"]["A"] = " ".join(uri_map)

			try:
				uri_map = _parse_uri_map(mysettings.mycpv, metadata)
			except InvalidDependString:
				mysettings.configdict["pkg"]["AA"] = ""
			else:
				mysettings.configdict["pkg"]["AA"] = " ".join(uri_map)

		ccache = "ccache" in mysettings.features
		distcc = "distcc" in mysettings.features
		if ccache or distcc:
			# Use default ABI libdir in accordance with bug #355283.
			libdir = None
			default_abi = mysettings.get("DEFAULT_ABI")
			if default_abi:
				libdir = mysettings.get("LIBDIR_" + default_abi)
			if not libdir:
				libdir = "lib"

			if distcc:
				mysettings["PATH"] = os.path.join(os.sep, eprefix_lstrip,
					 "usr", libdir, "distcc", "bin") + ":" + mysettings["PATH"]

			if ccache:
				mysettings["PATH"] = os.path.join(os.sep, eprefix_lstrip,
					 "usr", libdir, "ccache", "bin") + ":" + mysettings["PATH"]

		if not eapi_exports_KV(eapi):
			# Discard KV for EAPIs that don't support it. Cached KV is restored
			# from the backupenv whenever config.reset() is called.
			mysettings.pop('KV', None)
		elif 'KV' not in mysettings and \
			mydo in ('compile', 'config', 'configure', 'info',
			'install', 'nofetch', 'postinst', 'postrm', 'preinst',
			'prepare', 'prerm', 'setup', 'test', 'unpack'):
			mykv, err1 = ExtractKernelVersion(
				os.path.join(mysettings['EROOT'], "usr/src/linux"))
			if mykv:
				# Regular source tree
				mysettings["KV"] = mykv
			else:
				mysettings["KV"] = ""
			mysettings.backup_changes("KV")

_doebuild_manifest_cache = None
_doebuild_broken_ebuilds = set()
_doebuild_broken_manifests = set()
_doebuild_commands_without_builddir = (
	'clean', 'cleanrm', 'depend', 'digest',
	'fetch', 'fetchall', 'help', 'manifest'
)

def doebuild(myebuild, mydo, _unused=DeprecationWarning, settings=None, debug=0, listonly=0,
	fetchonly=0, cleanup=0, dbkey=DeprecationWarning, use_cache=1, fetchall=0, tree=None,
	mydbapi=None, vartree=None, prev_mtimes=None,
	fd_pipes=None, returnpid=False):
	"""
	Wrapper function that invokes specific ebuild phases through the spawning
	of ebuild.sh
	
	@param myebuild: name of the ebuild to invoke the phase on (CPV)
	@type myebuild: String
	@param mydo: Phase to run
	@type mydo: String
	@param _unused: Deprecated (use settings["ROOT"] instead)
	@type _unused: String
	@param settings: Portage Configuration
	@type settings: instance of portage.config
	@param debug: Turns on various debug information (eg, debug for spawn)
	@type debug: Boolean
	@param listonly: Used to wrap fetch(); passed such that fetch only lists files required.
	@type listonly: Boolean
	@param fetchonly: Used to wrap fetch(); passed such that files are only fetched (no other actions)
	@type fetchonly: Boolean
	@param cleanup: Passed to prepare_build_dirs (TODO: what does it do?)
	@type cleanup: Boolean
	@param dbkey: A file path where metadata generated by the 'depend' phase
		will be written.
	@type dbkey: String
	@param use_cache: Enables the cache
	@type use_cache: Boolean
	@param fetchall: Used to wrap fetch(), fetches all URIs (even ones invalid due to USE conditionals)
	@type fetchall: Boolean
	@param tree: Which tree to use ('vartree','porttree','bintree', etc..), defaults to 'porttree'
	@type tree: String
	@param mydbapi: a dbapi instance to pass to various functions; this should be a portdbapi instance.
	@type mydbapi: portdbapi instance
	@param vartree: A instance of vartree; used for aux_get calls, defaults to db[myroot]['vartree']
	@type vartree: vartree instance
	@param prev_mtimes: A dict of { filename:mtime } keys used by merge() to do config_protection
	@type prev_mtimes: dictionary
	@param fd_pipes: A dict of mapping for pipes, { '0': stdin, '1': stdout }
		for example.
	@type fd_pipes: Dictionary
	@param returnpid: Return a list of process IDs for a successful spawn, or
		an integer value if spawn is unsuccessful. NOTE: This requires the
		caller clean up all returned PIDs.
	@type returnpid: Boolean
	@rtype: Boolean
	@return:
	1. 0 for success
	2. 1 for error
	
	Most errors have an accompanying error message.
	
	listonly and fetchonly are only really necessary for operations involving 'fetch'
	prev_mtimes are only necessary for merge operations.
	Other variables may not be strictly required, many have defaults that are set inside of doebuild.
	
	"""

	if settings is None:
		raise TypeError("settings parameter is required")
	mysettings = settings
	myroot = settings['EROOT']

	if _unused is not DeprecationWarning:
		warnings.warn("The third parameter of the "
			"portage.doebuild() is deprecated. Instead "
			"settings['EROOT'] is used.",
			DeprecationWarning, stacklevel=2)

	if dbkey is not DeprecationWarning:
		warnings.warn("portage.doebuild() called "
			"with deprecated dbkey argument.",
			DeprecationWarning, stacklevel=2)

	if not tree:
		writemsg("Warning: tree not specified to doebuild\n")
		tree = "porttree"
	
	# chunked out deps for each phase, so that ebuild binary can use it 
	# to collapse targets down.
	actionmap_deps={
	"pretend"  : [],
	"setup":  ["pretend"],
	"unpack": ["setup"],
	"prepare": ["unpack"],
	"configure": ["prepare"],
	"compile":["configure"],
	"test":   ["compile"],
	"install":["test"],
	"rpm":    ["install"],
	"package":["install"],
	"merge"  :["install"],
	}
	
	if mydbapi is None:
		mydbapi = portage.db[myroot][tree].dbapi

	if vartree is None and mydo in ("merge", "qmerge", "unmerge"):
		vartree = portage.db[myroot]["vartree"]

	features = mysettings.features

	clean_phases = ("clean", "cleanrm")
	validcommands = ["help","clean","prerm","postrm","cleanrm","preinst","postinst",
	                "config", "info", "setup", "depend", "pretend",
	                "fetch", "fetchall", "digest",
	                "unpack", "prepare", "configure", "compile", "test",
	                "install", "rpm", "qmerge", "merge",
	                "package","unmerge", "manifest"]

	if mydo not in validcommands:
		validcommands.sort()
		writemsg("!!! doebuild: '%s' is not one of the following valid commands:" % mydo,
			noiselevel=-1)
		for vcount in range(len(validcommands)):
			if vcount%6 == 0:
				writemsg("\n!!! ", noiselevel=-1)
			writemsg(validcommands[vcount].ljust(11), noiselevel=-1)
		writemsg("\n", noiselevel=-1)
		return 1

	if returnpid and mydo != 'depend':
		warnings.warn("portage.doebuild() called " + \
			"with returnpid parameter enabled. This usage will " + \
			"not be supported in the future.",
			DeprecationWarning, stacklevel=2)

	if mydo == "fetchall":
		fetchall = 1
		mydo = "fetch"

	parallel_fetchonly = mydo in ("fetch", "fetchall") and \
		"PORTAGE_PARALLEL_FETCHONLY" in mysettings

	if mydo not in clean_phases and not os.path.exists(myebuild):
		writemsg("!!! doebuild: %s not found for %s\n" % (myebuild, mydo),
			noiselevel=-1)
		return 1

	global _doebuild_manifest_cache
	pkgdir = os.path.dirname(myebuild)
	manifest_path = os.path.join(pkgdir, "Manifest")
	if tree == "porttree":
		repo_config = mysettings.repositories.get_repo_for_location(
			os.path.dirname(os.path.dirname(pkgdir)))
	else:
		repo_config = None

	mf = None
	if "strict" in features and \
		"digest" not in features and \
		tree == "porttree" and \
		not repo_config.thin_manifest and \
		mydo not in ("digest", "manifest", "help") and \
		not portage._doebuild_manifest_exempt_depend and \
		not (repo_config.allow_missing_manifest and not os.path.exists(manifest_path)):
		# Always verify the ebuild checksums before executing it.
		global _doebuild_broken_ebuilds

		if myebuild in _doebuild_broken_ebuilds:
			return 1

		# Avoid checking the same Manifest several times in a row during a
		# regen with an empty cache.
		if _doebuild_manifest_cache is None or \
			_doebuild_manifest_cache.getFullname() != manifest_path:
			_doebuild_manifest_cache = None
			if not os.path.exists(manifest_path):
				out = portage.output.EOutput()
				out.eerror(_("Manifest not found for '%s'") % (myebuild,))
				_doebuild_broken_ebuilds.add(myebuild)
				return 1
			mf = repo_config.load_manifest(pkgdir, mysettings["DISTDIR"])

		else:
			mf = _doebuild_manifest_cache

		try:
			mf.checkFileHashes("EBUILD", os.path.basename(myebuild))
		except KeyError:
			if not (mf.allow_missing and
				os.path.basename(myebuild) not in mf.fhashdict["EBUILD"]):
				out = portage.output.EOutput()
				out.eerror(_("Missing digest for '%s'") % (myebuild,))
				_doebuild_broken_ebuilds.add(myebuild)
				return 1
		except FileNotFound:
			out = portage.output.EOutput()
			out.eerror(_("A file listed in the Manifest "
				"could not be found: '%s'") % (myebuild,))
			_doebuild_broken_ebuilds.add(myebuild)
			return 1
		except DigestException as e:
			out = portage.output.EOutput()
			out.eerror(_("Digest verification failed:"))
			out.eerror("%s" % e.value[0])
			out.eerror(_("Reason: %s") % e.value[1])
			out.eerror(_("Got: %s") % e.value[2])
			out.eerror(_("Expected: %s") % e.value[3])
			_doebuild_broken_ebuilds.add(myebuild)
			return 1

		if mf.getFullname() in _doebuild_broken_manifests:
			return 1

		if mf is not _doebuild_manifest_cache and not mf.allow_missing:

			# Make sure that all of the ebuilds are
			# actually listed in the Manifest.
			for f in os.listdir(pkgdir):
				pf = None
				if f[-7:] == '.ebuild':
					pf = f[:-7]
				if pf is not None and not mf.hasFile("EBUILD", f):
					f = os.path.join(pkgdir, f)
					if f not in _doebuild_broken_ebuilds:
						out = portage.output.EOutput()
						out.eerror(_("A file is not listed in the "
							"Manifest: '%s'") % (f,))
					_doebuild_broken_manifests.add(manifest_path)
					return 1

		# We cache it only after all above checks succeed.
		_doebuild_manifest_cache = mf

	logfile=None
	builddir_lock = None
	tmpdir = None
	tmpdir_orig = None

	try:
		if mydo in ("digest", "manifest", "help"):
			# Temporarily exempt the depend phase from manifest checks, in case
			# aux_get calls trigger cache generation.
			portage._doebuild_manifest_exempt_depend += 1

		# If we don't need much space and we don't need a constant location,
		# we can temporarily override PORTAGE_TMPDIR with a random temp dir
		# so that there's no need for locking and it can be used even if the
		# user isn't in the portage group.
		if mydo in ("info",):
			tmpdir = tempfile.mkdtemp()
			tmpdir_orig = mysettings["PORTAGE_TMPDIR"]
			mysettings["PORTAGE_TMPDIR"] = tmpdir

		doebuild_environment(myebuild, mydo, myroot, mysettings, debug,
			use_cache, mydbapi)

		if mydo in clean_phases:
			builddir_lock = None
			if not returnpid and \
				'PORTAGE_BUILDDIR_LOCKED' not in mysettings:
				builddir_lock = EbuildBuildDir(
					scheduler=(portage._internal_caller and
						global_event_loop() or EventLoop(main=False)),
					settings=mysettings)
				builddir_lock.lock()
			try:
				return _spawn_phase(mydo, mysettings,
					fd_pipes=fd_pipes, returnpid=returnpid)
			finally:
				if builddir_lock is not None:
					builddir_lock.unlock()

		# get possible slot information from the deps file
		if mydo == "depend":
			writemsg("!!! DEBUG: dbkey: %s\n" % str(dbkey), 2)
			if returnpid:
				return _spawn_phase(mydo, mysettings,
					fd_pipes=fd_pipes, returnpid=returnpid)
			elif dbkey and dbkey is not DeprecationWarning:
				mysettings["dbkey"] = dbkey
			else:
				mysettings["dbkey"] = \
					os.path.join(mysettings.depcachedir, "aux_db_key_temp")

			return _spawn_phase(mydo, mysettings,
				fd_pipes=fd_pipes, returnpid=returnpid)

		# Validate dependency metadata here to ensure that ebuilds with invalid
		# data are never installed via the ebuild command. Don't bother when
		# returnpid == True since there's no need to do this every time emerge
		# executes a phase.
		if tree == "porttree":
			rval = _validate_deps(mysettings, myroot, mydo, mydbapi)
			if rval != os.EX_OK:
				return rval

		else:
			# FEATURES=noauto only makes sense for porttree, and we don't want
			# it to trigger redundant sourcing of the ebuild for API consumers
			# that are using binary packages
			if "noauto" in mysettings.features:
				mysettings.features.discard("noauto")

		# The info phase is special because it uses mkdtemp so and
		# user (not necessarily in the portage group) can run it.
		if mydo not in ('info',) and \
			mydo not in _doebuild_commands_without_builddir:
			rval = _check_temp_dir(mysettings)
			if rval != os.EX_OK:
				return rval

		if mydo == "unmerge":
			return unmerge(mysettings["CATEGORY"],
				mysettings["PF"], myroot, mysettings, vartree=vartree)

		phases_to_run = set()
		if "noauto" in mysettings.features or \
			mydo not in actionmap_deps:
			phases_to_run.add(mydo)
		else:
			phase_stack = [mydo]
			while phase_stack:
				x = phase_stack.pop()
				if x in phases_to_run:
					continue
				phases_to_run.add(x)
				phase_stack.extend(actionmap_deps.get(x, []))
			del phase_stack

		alist = set(mysettings.configdict["pkg"].get("A", "").split())

		unpacked = False
		if tree != "porttree":
			pass
		elif "unpack" not in phases_to_run:
			unpacked = os.path.exists(os.path.join(
				mysettings["PORTAGE_BUILDDIR"], ".unpacked"))
		else:
			try:
				workdir_st = os.stat(mysettings["WORKDIR"])
			except OSError:
				pass
			else:
				newstuff = False
				if not os.path.exists(os.path.join(
					mysettings["PORTAGE_BUILDDIR"], ".unpacked")):
					writemsg_stdout(_(
						">>> Not marked as unpacked; recreating WORKDIR...\n"))
					newstuff = True
				else:
					for x in alist:
						writemsg_stdout(">>> Checking %s's mtime...\n" % x)
						try:
							x_st = os.stat(os.path.join(
								mysettings["DISTDIR"], x))
						except OSError:
							# file not fetched yet
							x_st = None

						if x_st is None or x_st.st_mtime > workdir_st.st_mtime:
							writemsg_stdout(_(">>> Timestamp of "
								"%s has changed; recreating WORKDIR...\n") % x)
							newstuff = True
							break

				if newstuff:
					if builddir_lock is None and \
						'PORTAGE_BUILDDIR_LOCKED' not in mysettings:
						builddir_lock = EbuildBuildDir(
							scheduler=(portage._internal_caller and
								global_event_loop() or EventLoop(main=False)),
							settings=mysettings)
						builddir_lock.lock()
					try:
						_spawn_phase("clean", mysettings)
					finally:
						if builddir_lock is not None:
							builddir_lock.unlock()
							builddir_lock = None
				else:
					writemsg_stdout(_(">>> WORKDIR is up-to-date, keeping...\n"))
					unpacked = True

		# Build directory creation isn't required for any of these.
		# In the fetch phase, the directory is needed only for RESTRICT=fetch
		# in order to satisfy the sane $PWD requirement (from bug #239560)
		# when pkg_nofetch is spawned.
		have_build_dirs = False
		if not parallel_fetchonly and \
			mydo not in ('digest', 'fetch', 'help', 'manifest'):
			if not returnpid and \
				'PORTAGE_BUILDDIR_LOCKED' not in mysettings:
				builddir_lock = EbuildBuildDir(
					scheduler=(portage._internal_caller and
						global_event_loop() or EventLoop(main=False)),
					settings=mysettings)
				builddir_lock.lock()
			mystatus = prepare_build_dirs(myroot, mysettings, cleanup)
			if mystatus:
				return mystatus
			have_build_dirs = True

			# emerge handles logging externally
			if not returnpid:
				# PORTAGE_LOG_FILE is set by the
				# above prepare_build_dirs() call.
				logfile = mysettings.get("PORTAGE_LOG_FILE")

		if have_build_dirs:
			rval = _prepare_env_file(mysettings)
			if rval != os.EX_OK:
				return rval

		if eapi_exports_merge_type(mysettings["EAPI"]) and \
			"MERGE_TYPE" not in mysettings.configdict["pkg"]:
			if tree == "porttree":
				mysettings.configdict["pkg"]["EMERGE_FROM"] = "ebuild"
				mysettings.configdict["pkg"]["MERGE_TYPE"] = "source"
			elif tree == "bintree":
				mysettings.configdict["pkg"]["EMERGE_FROM"] = "binary"
				mysettings.configdict["pkg"]["MERGE_TYPE"] = "binary"

		# NOTE: It's not possible to set REPLACED_BY_VERSION for prerm
		#       and postrm here, since we don't necessarily know what
		#       versions are being installed. This could be a problem
		#       for API consumers if they don't use dblink.treewalk()
		#       to execute prerm and postrm.
		if eapi_exports_replace_vars(mysettings["EAPI"]) and \
			(mydo in ("postinst", "preinst", "pretend", "setup") or \
			("noauto" not in features and not returnpid and \
			(mydo in actionmap_deps or mydo in ("merge", "package", "qmerge")))):
			if not vartree:
				writemsg("Warning: vartree not given to doebuild. " + \
					"Cannot set REPLACING_VERSIONS in pkg_{pretend,setup}\n")
			else:
				vardb = vartree.dbapi
				cpv = mysettings.mycpv
				cpv_slot = "%s%s%s" % \
					(cpv.cp, portage.dep._slot_separator, cpv.slot)
				mysettings["REPLACING_VERSIONS"] = " ".join(
					set(portage.versions.cpv_getversion(match) \
						for match in vardb.match(cpv_slot) + \
						vardb.match('='+cpv)))

		# if any of these are being called, handle them -- running them out of
		# the sandbox -- and stop now.
		if mydo in ("config", "help", "info", "postinst",
			"preinst", "pretend", "postrm", "prerm"):
			if mydo in ("preinst", "postinst"):
				env_file = os.path.join(os.path.dirname(mysettings["EBUILD"]),
					"environment.bz2")
				if os.path.isfile(env_file):
					mysettings["PORTAGE_UPDATE_ENV"] = env_file
			try:
				return _spawn_phase(mydo, mysettings,
					fd_pipes=fd_pipes, logfile=logfile, returnpid=returnpid)
			finally:
				mysettings.pop("PORTAGE_UPDATE_ENV", None)

		mycpv = "/".join((mysettings["CATEGORY"], mysettings["PF"]))

		# Only try and fetch the files if we are going to need them ...
		# otherwise, if user has FEATURES=noauto and they run `ebuild clean
		# unpack compile install`, we will try and fetch 4 times :/
		need_distfiles = tree == "porttree" and not unpacked and \
			(mydo in ("fetch", "unpack") or \
			mydo not in ("digest", "manifest") and "noauto" not in features)
		if need_distfiles:

			src_uri, = mydbapi.aux_get(mysettings.mycpv,
				["SRC_URI"], mytree=os.path.dirname(os.path.dirname(
				os.path.dirname(myebuild))))
			metadata = {
				"EAPI"    : mysettings["EAPI"],
				"SRC_URI" : src_uri,
			}
			use = frozenset(mysettings["PORTAGE_USE"].split())
			try:
				alist = _parse_uri_map(mysettings.mycpv, metadata, use=use)
				aalist = _parse_uri_map(mysettings.mycpv, metadata)
			except InvalidDependString as e:
				writemsg("!!! %s\n" % str(e), noiselevel=-1)
				writemsg(_("!!! Invalid SRC_URI for '%s'.\n") % mycpv,
					noiselevel=-1)
				del e
				return 1

			if "mirror" in features or fetchall:
				fetchme = aalist
			else:
				fetchme = alist

			dist_digests = None
			if mf is not None:
				dist_digests = mf.getTypeDigests("DIST")
			if not fetch(fetchme, mysettings, listonly=listonly,
				fetchonly=fetchonly, allow_missing_digests=True,
				digests=dist_digests):
				spawn_nofetch(mydbapi, myebuild, settings=mysettings)
				if listonly:
					# The convention for listonly mode is to report
					# success in any case, even though fetch() may
					# return unsuccessfully in order to trigger the
					# nofetch phase.
					return 0
				return 1

		if need_distfiles:
			# Files are already checked inside fetch(),
			# so do not check them again.
			checkme = []
		elif unpacked:
			# The unpack phase is marked as complete, so it
			# would be wasteful to check distfiles again.
			checkme = []
		else:
			checkme = alist

		if mydo == "fetch" and listonly:
			return 0

		try:
			if mydo == "manifest":
				mf = None
				_doebuild_manifest_cache = None
				return not digestgen(mysettings=mysettings, myportdb=mydbapi)
			elif mydo == "digest":
				mf = None
				_doebuild_manifest_cache = None
				return not digestgen(mysettings=mysettings, myportdb=mydbapi)
			elif mydo != 'fetch' and \
				"digest" in mysettings.features:
				# Don't do this when called by emerge or when called just
				# for fetch (especially parallel-fetch) since it's not needed
				# and it can interfere with parallel tasks.
				mf = None
				_doebuild_manifest_cache = None
				digestgen(mysettings=mysettings, myportdb=mydbapi)
		except PermissionDenied as e:
			writemsg(_("!!! Permission Denied: %s\n") % (e,), noiselevel=-1)
			if mydo in ("digest", "manifest"):
				return 1

		# See above comment about fetching only when needed
		if tree == 'porttree' and \
			not digestcheck(checkme, mysettings, "strict" in features, mf=mf):
			return 1

		if mydo == "fetch":
			return 0

		# remove PORTAGE_ACTUAL_DISTDIR once cvs/svn is supported via SRC_URI
		if tree == 'porttree' and \
			((mydo != "setup" and "noauto" not in features) \
			or mydo in ("install", "unpack")):
			_prepare_fake_distdir(mysettings, alist)

		#initial dep checks complete; time to process main commands
		actionmap = _spawn_actionmap(mysettings)

		# merge the deps in so we have again a 'full' actionmap
		# be glad when this can die.
		for x in actionmap:
			if len(actionmap_deps.get(x, [])):
				actionmap[x]["dep"] = ' '.join(actionmap_deps[x])

		if mydo in actionmap:
			bintree = None
			if mydo == "package":
				# Make sure the package directory exists before executing
				# this phase. This can raise PermissionDenied if
				# the current user doesn't have write access to $PKGDIR.
				if hasattr(portage, 'db'):
					bintree = portage.db[mysettings['EROOT']]['bintree']
					mysettings["PORTAGE_BINPKG_TMPFILE"] = \
						bintree.getname(mysettings.mycpv) + \
						".%s" % (os.getpid(),)
					bintree._ensure_dir(os.path.dirname(
						mysettings["PORTAGE_BINPKG_TMPFILE"]))
				else:
					parent_dir = os.path.join(mysettings["PKGDIR"],
						mysettings["CATEGORY"])
					portage.util.ensure_dirs(parent_dir)
					if not os.access(parent_dir, os.W_OK):
						raise PermissionDenied(
							"access('%s', os.W_OK)" % parent_dir)
			retval = spawnebuild(mydo,
				actionmap, mysettings, debug, logfile=logfile,
				fd_pipes=fd_pipes, returnpid=returnpid)

			if retval == os.EX_OK:
				if mydo == "package" and bintree is not None:
					bintree.inject(mysettings.mycpv,
						filename=mysettings["PORTAGE_BINPKG_TMPFILE"])
			else:
				if "PORTAGE_BINPKG_TMPFILE" in mysettings:
					try:
						os.unlink(mysettings["PORTAGE_BINPKG_TMPFILE"])
					except OSError:
						pass

		elif mydo=="qmerge":
			# check to ensure install was run.  this *only* pops up when users
			# forget it and are using ebuild
			if not os.path.exists(
				os.path.join(mysettings["PORTAGE_BUILDDIR"], ".installed")):
				writemsg(_("!!! mydo=qmerge, but the install phase has not been run\n"),
					noiselevel=-1)
				return 1
			# qmerge is a special phase that implies noclean.
			if "noclean" not in mysettings.features:
				mysettings.features.add("noclean")
			_handle_self_update(mysettings, vartree.dbapi)
			#qmerge is specifically not supposed to do a runtime dep check
			retval = merge(
				mysettings["CATEGORY"], mysettings["PF"], mysettings["D"],
				os.path.join(mysettings["PORTAGE_BUILDDIR"], "build-info"),
				myroot, mysettings, myebuild=mysettings["EBUILD"], mytree=tree,
				mydbapi=mydbapi, vartree=vartree, prev_mtimes=prev_mtimes)
		elif mydo=="merge":
			retval = spawnebuild("install", actionmap, mysettings, debug,
				alwaysdep=1, logfile=logfile, fd_pipes=fd_pipes,
				returnpid=returnpid)
			if retval != os.EX_OK:
				# The merge phase handles this already.  Callers don't know how
				# far this function got, so we have to call elog_process() here
				# so that it's only called once.
				elog_process(mysettings.mycpv, mysettings)
			if retval == os.EX_OK:
				_handle_self_update(mysettings, vartree.dbapi)
				retval = merge(mysettings["CATEGORY"], mysettings["PF"],
					mysettings["D"], os.path.join(mysettings["PORTAGE_BUILDDIR"],
					"build-info"), myroot, mysettings,
					myebuild=mysettings["EBUILD"], mytree=tree, mydbapi=mydbapi,
					vartree=vartree, prev_mtimes=prev_mtimes)
		else:
			writemsg_stdout(_("!!! Unknown mydo: %s\n") % mydo, noiselevel=-1)
			return 1

		return retval

	finally:

		if builddir_lock is not None:
			builddir_lock.unlock()
		if tmpdir:
			mysettings["PORTAGE_TMPDIR"] = tmpdir_orig
			shutil.rmtree(tmpdir)

		mysettings.pop("REPLACING_VERSIONS", None)

		# Make sure that DISTDIR is restored to it's normal value before we return!
		if "PORTAGE_ACTUAL_DISTDIR" in mysettings:
			mysettings["DISTDIR"] = mysettings["PORTAGE_ACTUAL_DISTDIR"]
			del mysettings["PORTAGE_ACTUAL_DISTDIR"]

		if logfile and not returnpid:
			try:
				if os.stat(logfile).st_size == 0:
					os.unlink(logfile)
			except OSError:
				pass

		if mydo in ("digest", "manifest", "help"):
			# If necessary, depend phase has been triggered by aux_get calls
			# and the exemption is no longer needed.
			portage._doebuild_manifest_exempt_depend -= 1

def _check_temp_dir(settings):
	if "PORTAGE_TMPDIR" not in settings or \
		not os.path.isdir(settings["PORTAGE_TMPDIR"]):
		writemsg(_("The directory specified in your "
			"PORTAGE_TMPDIR variable, '%s',\n"
			"does not exist.  Please create this directory or "
			"correct your PORTAGE_TMPDIR setting.\n") % \
			settings.get("PORTAGE_TMPDIR", ""), noiselevel=-1)
		return 1

	# as some people use a separate PORTAGE_TMPDIR mount
	# we prefer that as the checks below would otherwise be pointless
	# for those people.
	tmpdir = os.path.realpath(settings["PORTAGE_TMPDIR"])
	if os.path.exists(os.path.join(tmpdir, "portage")):
		checkdir = os.path.realpath(os.path.join(tmpdir, "portage"))
		if ("sandbox" in settings.features or
			"usersandox" in settings.features) and \
			not checkdir.startswith(tmpdir + os.sep):
			msg = _("The 'portage' subdirectory of the directory "
			"referenced by the PORTAGE_TMPDIR variable appears to be "
			"a symlink. In order to avoid sandbox violations (see bug "
			"#378379), you must adjust PORTAGE_TMPDIR instead of using "
			"the symlink located at '%s'. A suitable PORTAGE_TMPDIR "
			"setting would be '%s'.") % \
			(os.path.join(tmpdir, "portage"), checkdir)
			lines = []
			lines.append("")
			lines.append("")
			lines.extend(wrap(msg, 72))
			lines.append("")
			for line in lines:
				if line:
					line = "!!! %s" % (line,)
				writemsg("%s\n" % (line,), noiselevel=-1)
			return 1
	else:
		checkdir = tmpdir

	if not os.access(checkdir, os.W_OK):
		writemsg(_("%s is not writable.\n"
			"Likely cause is that you've mounted it as readonly.\n") % checkdir,
			noiselevel=-1)
		return 1

	with tempfile.NamedTemporaryFile(prefix="exectest-", dir=checkdir) as fd:
		os.chmod(fd.name, 0o755)
		if not os.access(fd.name, os.X_OK):
			writemsg(_("Can not execute files in %s\n"
				"Likely cause is that you've mounted it with one of the\n"
				"following mount options: 'noexec', 'user', 'users'\n\n"
				"Please make sure that portage can execute files in this directory.\n") % checkdir,
				noiselevel=-1)
			return 1

	return os.EX_OK

def _prepare_env_file(settings):
	"""
	Extract environment.bz2 if it exists, but only if the destination
	environment file doesn't already exist. There are lots of possible
	states when doebuild() calls this function, and we want to avoid
	clobbering an existing environment file.
	"""

	env_extractor = BinpkgEnvExtractor(background=False,
		scheduler=(portage._internal_caller and
			global_event_loop() or EventLoop(main=False)),
		settings=settings)

	if env_extractor.dest_env_exists():
		# There are lots of possible states when doebuild()
		# calls this function, and we want to avoid
		# clobbering an existing environment file.
		return os.EX_OK

	if not env_extractor.saved_env_exists():
		# If the environment.bz2 doesn't exist, then ebuild.sh will
		# source the ebuild as a fallback.
		return os.EX_OK

	env_extractor.start()
	env_extractor.wait()
	return env_extractor.returncode

def _prepare_fake_distdir(settings, alist):
	orig_distdir = settings["DISTDIR"]
	settings["PORTAGE_ACTUAL_DISTDIR"] = orig_distdir
	edpath = settings["DISTDIR"] = \
		os.path.join(settings["PORTAGE_BUILDDIR"], "distdir")
	portage.util.ensure_dirs(edpath, gid=portage_gid, mode=0o755)

	# Remove any unexpected files or directories.
	for x in os.listdir(edpath):
		symlink_path = os.path.join(edpath, x)
		st = os.lstat(symlink_path)
		if x in alist and stat.S_ISLNK(st.st_mode):
			continue
		if stat.S_ISDIR(st.st_mode):
			shutil.rmtree(symlink_path)
		else:
			os.unlink(symlink_path)

	# Check for existing symlinks and recreate if necessary.
	for x in alist:
		symlink_path = os.path.join(edpath, x)
		target = os.path.join(orig_distdir, x)
		try:
			link_target = os.readlink(symlink_path)
		except OSError:
			os.symlink(target, symlink_path)
		else:
			if link_target != target:
				os.unlink(symlink_path)
				os.symlink(target, symlink_path)

def _spawn_actionmap(settings):
	features = settings.features
	restrict = settings["PORTAGE_RESTRICT"].split()
	nosandbox = (("userpriv" in features) and \
		("usersandbox" not in features) and \
		"userpriv" not in restrict and \
		"nouserpriv" not in restrict)
	if nosandbox and ("userpriv" not in features or \
		"userpriv" in restrict or \
		"nouserpriv" in restrict):
		nosandbox = ("sandbox" not in features and \
			"usersandbox" not in features)

	if not portage.process.sandbox_capable:
		nosandbox = True

	sesandbox = settings.selinux_enabled() and \
		"sesandbox" in features

	droppriv = "userpriv" in features and \
		"userpriv" not in restrict and \
		secpass >= 2

	fakeroot = "fakeroot" in features

	portage_bin_path = settings["PORTAGE_BIN_PATH"]
	ebuild_sh_binary = os.path.join(portage_bin_path,
		os.path.basename(EBUILD_SH_BINARY))
	misc_sh_binary = os.path.join(portage_bin_path,
		os.path.basename(MISC_SH_BINARY))
	ebuild_sh = _shell_quote(ebuild_sh_binary) + " %s"
	misc_sh = _shell_quote(misc_sh_binary) + " __dyn_%s"

	# args are for the to spawn function
	actionmap = {
"pretend":  {"cmd":ebuild_sh, "args":{"droppriv":0,        "free":1,         "sesandbox":0,         "fakeroot":0}},
"setup":    {"cmd":ebuild_sh, "args":{"droppriv":0,        "free":1,         "sesandbox":0,         "fakeroot":0}},
"unpack":   {"cmd":ebuild_sh, "args":{"droppriv":droppriv, "free":0,         "sesandbox":sesandbox, "fakeroot":0}},
"prepare":  {"cmd":ebuild_sh, "args":{"droppriv":droppriv, "free":0,         "sesandbox":sesandbox, "fakeroot":0}},
"configure":{"cmd":ebuild_sh, "args":{"droppriv":droppriv, "free":nosandbox, "sesandbox":sesandbox, "fakeroot":0}},
"compile":  {"cmd":ebuild_sh, "args":{"droppriv":droppriv, "free":nosandbox, "sesandbox":sesandbox, "fakeroot":0}},
"test":     {"cmd":ebuild_sh, "args":{"droppriv":droppriv, "free":nosandbox, "sesandbox":sesandbox, "fakeroot":0}},
"install":  {"cmd":ebuild_sh, "args":{"droppriv":0,        "free":0,         "sesandbox":sesandbox, "fakeroot":fakeroot}},
"rpm":      {"cmd":misc_sh,   "args":{"droppriv":0,        "free":0,         "sesandbox":0,         "fakeroot":fakeroot}},
"package":  {"cmd":misc_sh,   "args":{"droppriv":0,        "free":0,         "sesandbox":0,         "fakeroot":fakeroot}},
		}

	return actionmap

def _validate_deps(mysettings, myroot, mydo, mydbapi):

	invalid_dep_exempt_phases = \
		set(["clean", "cleanrm", "help", "prerm", "postrm"])
	all_keys = set(Package.metadata_keys)
	all_keys.add("SRC_URI")
	all_keys = tuple(all_keys)
	metadata = dict(zip(all_keys,
		mydbapi.aux_get(mysettings.mycpv, all_keys,
		myrepo=mysettings.get("PORTAGE_REPO_NAME"))))

	class FakeTree(object):
		def __init__(self, mydb):
			self.dbapi = mydb

	root_config = RootConfig(mysettings, {"porttree":FakeTree(mydbapi)}, None)

	pkg = Package(built=False, cpv=mysettings.mycpv,
		metadata=metadata, root_config=root_config,
		type_name="ebuild")

	msgs = []
	if pkg.invalid:
		for k, v in pkg.invalid.items():
			for msg in v:
				msgs.append("  %s\n" % (msg,))

	if msgs:
		portage.util.writemsg_level(_("Error(s) in metadata for '%s':\n") % \
			(mysettings.mycpv,), level=logging.ERROR, noiselevel=-1)
		for x in msgs:
			portage.util.writemsg_level(x,
				level=logging.ERROR, noiselevel=-1)
		if mydo not in invalid_dep_exempt_phases:
			return 1

	if not pkg.built and \
		mydo not in ("digest", "help", "manifest") and \
		pkg._metadata["REQUIRED_USE"] and \
		eapi_has_required_use(pkg.eapi):
		result = check_required_use(pkg._metadata["REQUIRED_USE"],
			pkg.use.enabled, pkg.iuse.is_valid_flag, eapi=pkg.eapi)
		if not result:
			reduced_noise = result.tounicode()
			writemsg("\n  %s\n" % _("The following REQUIRED_USE flag" + \
				" constraints are unsatisfied:"), noiselevel=-1)
			writemsg("    %s\n" % reduced_noise,
				noiselevel=-1)
			normalized_required_use = \
				" ".join(pkg._metadata["REQUIRED_USE"].split())
			if reduced_noise != normalized_required_use:
				writemsg("\n  %s\n" % _("The above constraints " + \
					"are a subset of the following complete expression:"),
					noiselevel=-1)
				writemsg("    %s\n" % \
					human_readable_required_use(normalized_required_use),
					noiselevel=-1)
			writemsg("\n", noiselevel=-1)
			return 1

	return os.EX_OK

# XXX This would be to replace getstatusoutput completely.
# XXX Issue: cannot block execution. Deadlock condition.
def spawn(mystring, mysettings, debug=0, free=0, droppriv=0, sesandbox=0, fakeroot=0, **keywords):
	"""
	Spawn a subprocess with extra portage-specific options.
	Optiosn include:

	Sandbox: Sandbox means the spawned process will be limited in its ability t
	read and write files (normally this means it is restricted to ${D}/)
	SElinux Sandbox: Enables sandboxing on SElinux
	Reduced Privileges: Drops privilages such that the process runs as portage:portage
	instead of as root.

	Notes: os.system cannot be used because it messes with signal handling.  Instead we
	use the portage.process spawn* family of functions.

	This function waits for the process to terminate.

	@param mystring: Command to run
	@type mystring: String
	@param mysettings: Either a Dict of Key,Value pairs or an instance of portage.config
	@type mysettings: Dictionary or config instance
	@param debug: Ignored
	@type debug: Boolean
	@param free: Enable sandboxing for this process
	@type free: Boolean
	@param droppriv: Drop to portage:portage when running this command
	@type droppriv: Boolean
	@param sesandbox: Enable SELinux Sandboxing (toggles a context switch)
	@type sesandbox: Boolean
	@param fakeroot: Run this command with faked root privileges
	@type fakeroot: Boolean
	@param keywords: Extra options encoded as a dict, to be passed to spawn
	@type keywords: Dictionary
	@rtype: Integer
	@return:
	1. The return code of the spawned process.
	"""

	check_config_instance(mysettings)

	fd_pipes = keywords.get("fd_pipes")
	if fd_pipes is None:
		fd_pipes = {
			0:portage._get_stdin().fileno(),
			1:sys.__stdout__.fileno(),
			2:sys.__stderr__.fileno(),
		}
	# In some cases the above print statements don't flush stdout, so
	# it needs to be flushed before allowing a child process to use it
	# so that output always shows in the correct order.
	stdout_filenos = (sys.__stdout__.fileno(), sys.__stderr__.fileno())
	for fd in fd_pipes.values():
		if fd in stdout_filenos:
			sys.__stdout__.flush()
			sys.__stderr__.flush()
			break

	features = mysettings.features
	# TODO: Enable fakeroot to be used together with droppriv.  The
	# fake ownership/permissions will have to be converted to real
	# permissions in the merge phase.
	fakeroot = fakeroot and uid != 0 and portage.process.fakeroot_capable
	portage_build_uid = os.getuid()
	portage_build_gid = os.getgid()
	if uid == 0 and portage_uid and portage_gid and hasattr(os, "setgroups"):
		if droppriv:
			keywords.update({
				"uid": portage_uid,
				"gid": portage_gid,
				"groups": userpriv_groups,
				"umask": 0o02
			})
		if "userpriv" in features and "userpriv" not in mysettings["PORTAGE_RESTRICT"].split() and secpass >= 2:
			portage_build_uid = portage_uid
			portage_build_gid = portage_gid
	mysettings["PORTAGE_BUILD_USER"] = pwd.getpwuid(portage_build_uid).pw_name
	mysettings["PORTAGE_BUILD_GROUP"] = grp.getgrgid(portage_build_gid).gr_name

	if not free:
		free=((droppriv and "usersandbox" not in features) or \
			(not droppriv and "sandbox" not in features and \
			"usersandbox" not in features and not fakeroot))

	if not free and not (fakeroot or portage.process.sandbox_capable):
		free = True

	if mysettings.mycpv is not None:
		keywords["opt_name"] = "[%s]" % mysettings.mycpv
	else:
		keywords["opt_name"] = "[%s/%s]" % \
			(mysettings.get("CATEGORY",""), mysettings.get("PF",""))

	if free or "SANDBOX_ACTIVE" in os.environ:
		keywords["opt_name"] += " bash"
		spawn_func = portage.process.spawn_bash
	elif fakeroot:
		keywords["opt_name"] += " fakeroot"
		keywords["fakeroot_state"] = os.path.join(mysettings["T"], "fakeroot.state")
		spawn_func = portage.process.spawn_fakeroot
	else:
		keywords["opt_name"] += " sandbox"
		spawn_func = portage.process.spawn_sandbox

	if sesandbox:
		spawn_func = selinux.spawn_wrapper(spawn_func,
			mysettings["PORTAGE_SANDBOX_T"])

	if keywords.get("returnpid"):
		return spawn_func(mystring, env=mysettings.environ(),
			**portage._native_kwargs(keywords))

	proc = EbuildSpawnProcess(
		background=False, args=mystring,
		scheduler=SchedulerInterface(portage._internal_caller and
			global_event_loop() or EventLoop(main=False)),
		spawn_func=spawn_func,
		settings=mysettings, **portage._native_kwargs(keywords))

	proc.start()
	proc.wait()

	return proc.returncode

# parse actionmap to spawn ebuild with the appropriate args
def spawnebuild(mydo, actionmap, mysettings, debug, alwaysdep=0,
	logfile=None, fd_pipes=None, returnpid=False):

	if returnpid:
		warnings.warn("portage.spawnebuild() called " + \
			"with returnpid parameter enabled. This usage will " + \
			"not be supported in the future.",
			DeprecationWarning, stacklevel=2)

	if not returnpid and \
		(alwaysdep or "noauto" not in mysettings.features):
		# process dependency first
		if "dep" in actionmap[mydo]:
			retval = spawnebuild(actionmap[mydo]["dep"], actionmap,
				mysettings, debug, alwaysdep=alwaysdep, logfile=logfile,
				fd_pipes=fd_pipes, returnpid=returnpid)
			if retval:
				return retval

	eapi = mysettings["EAPI"]

	if mydo in ("configure", "prepare") and not eapi_has_src_prepare_and_src_configure(eapi):
		return os.EX_OK

	if mydo == "pretend" and not eapi_has_pkg_pretend(eapi):
		return os.EX_OK

	if not (mydo == "install" and "noauto" in mysettings.features):
		check_file = os.path.join(
			mysettings["PORTAGE_BUILDDIR"], ".%sed" % mydo.rstrip('e'))
		if os.path.exists(check_file):
			writemsg_stdout(_(">>> It appears that "
				"'%(action)s' has already executed for '%(pkg)s'; skipping.\n") %
				{"action":mydo, "pkg":mysettings["PF"]})
			writemsg_stdout(_(">>> Remove '%(file)s' to force %(action)s.\n") %
				{"file":check_file, "action":mydo})
			return os.EX_OK

	return _spawn_phase(mydo, mysettings,
		actionmap=actionmap, logfile=logfile,
		fd_pipes=fd_pipes, returnpid=returnpid)

_post_phase_cmds = {

	"install" : [
		"install_qa_check",
		"install_symlink_html_docs",
		"install_hooks"],

	"preinst" : [
		"preinst_sfperms",
		"preinst_selinux_labels",
		"preinst_suid_scan",
		]
}

def _post_phase_userpriv_perms(mysettings):
	if "userpriv" in mysettings.features and secpass >= 2:
		""" Privileged phases may have left files that need to be made
		writable to a less privileged user."""
		apply_recursive_permissions(mysettings["T"],
			uid=portage_uid, gid=portage_gid, dirmode=0o70, dirmask=0,
			filemode=0o60, filemask=0)

def _check_build_log(mysettings, out=None):
	"""
	Search the content of $PORTAGE_LOG_FILE if it exists
	and generate the following QA Notices when appropriate:

	  * Automake "maintainer mode"
	  * command not found
	  * Unrecognized configure options
	"""
	logfile = mysettings.get("PORTAGE_LOG_FILE")
	if logfile is None:
		return
	try:
		f = open(_unicode_encode(logfile, encoding=_encodings['fs'],
			errors='strict'), mode='rb')
	except EnvironmentError:
		return

	f_real = None
	if logfile.endswith('.gz'):
		f_real = f
		f =  gzip.GzipFile(filename='', mode='rb', fileobj=f)

	am_maintainer_mode = []
	bash_command_not_found = []
	bash_command_not_found_re = re.compile(
		r'(.*): line (\d*): (.*): command not found$')
	command_not_found_exclude_re = re.compile(r'/configure: line ')
	helper_missing_file = []
	helper_missing_file_re = re.compile(
		r'^!!! (do|new).*: .* does not exist$')

	configure_opts_warn = []
	configure_opts_warn_re = re.compile(
		r'^configure: WARNING: [Uu]nrecognized options: (.*)')

	qa_configure_opts = ""
	try:
		with io.open(_unicode_encode(os.path.join(
			mysettings["PORTAGE_BUILDDIR"],
			"build-info", "QA_CONFIGURE_OPTIONS"),
			encoding=_encodings['fs'], errors='strict'),
			mode='r', encoding=_encodings['repo.content'],
			errors='replace') as qa_configure_opts_f:
			qa_configure_opts = qa_configure_opts_f.read()
	except IOError as e:
		if e.errno not in (errno.ENOENT, errno.ESTALE):
			raise

	qa_configure_opts = qa_configure_opts.split()
	if qa_configure_opts:
		if len(qa_configure_opts) > 1:
			qa_configure_opts = "|".join("(%s)" % x for x in qa_configure_opts)
			qa_configure_opts = "^(%s)$" % qa_configure_opts
		else:
			qa_configure_opts = "^%s$" % qa_configure_opts[0]
		qa_configure_opts = re.compile(qa_configure_opts)

	qa_am_maintainer_mode = []
	try:
		with io.open(_unicode_encode(os.path.join(
			mysettings["PORTAGE_BUILDDIR"],
			"build-info", "QA_AM_MAINTAINER_MODE"),
			encoding=_encodings['fs'], errors='strict'),
			mode='r', encoding=_encodings['repo.content'],
			errors='replace') as qa_am_maintainer_mode_f:
			qa_am_maintainer_mode = [x for x in
				qa_am_maintainer_mode_f.read().splitlines() if x]
	except IOError as e:
		if e.errno not in (errno.ENOENT, errno.ESTALE):
			raise

	if qa_am_maintainer_mode:
		if len(qa_am_maintainer_mode) > 1:
			qa_am_maintainer_mode = \
				"|".join("(%s)" % x for x in qa_am_maintainer_mode)
			qa_am_maintainer_mode = "^(%s)$" % qa_am_maintainer_mode
		else:
			qa_am_maintainer_mode = "^%s$" % qa_am_maintainer_mode[0]
		qa_am_maintainer_mode = re.compile(qa_am_maintainer_mode)

	# Exclude output from dev-libs/yaz-3.0.47 which looks like this:
	#
	#Configuration:
	#  Automake:                   ${SHELL} /var/tmp/portage/dev-libs/yaz-3.0.47/work/yaz-3.0.47/config/missing --run automake-1.10
	am_maintainer_mode_re = re.compile(r'/missing --run ')
	am_maintainer_mode_exclude_re = \
		re.compile(r'(/missing --run (autoheader|autotest|help2man|makeinfo)|^\s*Automake:\s)')

	make_jobserver_re = \
		re.compile(r'g?make\[\d+\]: warning: jobserver unavailable:')
	make_jobserver = []

	def _eerror(lines):
		for line in lines:
			eerror(line, phase="install", key=mysettings.mycpv, out=out)

	try:
		for line in f:
			line = _unicode_decode(line)
			if am_maintainer_mode_re.search(line) is not None and \
				am_maintainer_mode_exclude_re.search(line) is None and \
				(not qa_am_maintainer_mode or
					qa_am_maintainer_mode.search(line) is None):
				am_maintainer_mode.append(line.rstrip("\n"))

			if bash_command_not_found_re.match(line) is not None and \
				command_not_found_exclude_re.search(line) is None:
				bash_command_not_found.append(line.rstrip("\n"))

			if helper_missing_file_re.match(line) is not None:
				helper_missing_file.append(line.rstrip("\n"))

			m = configure_opts_warn_re.match(line)
			if m is not None:
				for x in m.group(1).split(", "):
					if not qa_configure_opts or qa_configure_opts.match(x) is None:
						configure_opts_warn.append(x)

			if make_jobserver_re.match(line) is not None:
				make_jobserver.append(line.rstrip("\n"))

	except zlib.error as e:
		_eerror(["portage encountered a zlib error: '%s'" % (e,),
			"while reading the log file: '%s'" % logfile])
	finally:
		f.close()

	def _eqawarn(lines):
		for line in lines:
			eqawarn(line, phase="install", key=mysettings.mycpv, out=out)
	wrap_width = 70

	if am_maintainer_mode:
		msg = [_("QA Notice: Automake \"maintainer mode\" detected:")]
		msg.append("")
		msg.extend("\t" + line for line in am_maintainer_mode)
		msg.append("")
		msg.extend(wrap(_(
			"If you patch Makefile.am, "
			"configure.in,  or configure.ac then you "
			"should use autotools.eclass and "
			"eautomake or eautoreconf. Exceptions "
			"are limited to system packages "
			"for which it is impossible to run "
			"autotools during stage building. "
			"See http://www.gentoo.org/p"
			"roj/en/qa/autofailure.xml for more information."),
			wrap_width))
		_eqawarn(msg)

	if bash_command_not_found:
		msg = [_("QA Notice: command not found:")]
		msg.append("")
		msg.extend("\t" + line for line in bash_command_not_found)
		_eqawarn(msg)

	if helper_missing_file:
		msg = [_("QA Notice: file does not exist:")]
		msg.append("")
		msg.extend("\t" + line[4:] for line in helper_missing_file)
		_eqawarn(msg)

	if configure_opts_warn:
		msg = [_("QA Notice: Unrecognized configure options:")]
		msg.append("")
		msg.extend("\t%s" % x for x in configure_opts_warn)
		_eqawarn(msg)

	if make_jobserver:
		msg = [_("QA Notice: make jobserver unavailable:")]
		msg.append("")
		msg.extend("\t" + line for line in make_jobserver)
		_eqawarn(msg)

	f.close()
	if f_real is not None:
		f_real.close()

def _post_src_install_write_metadata(settings):
	"""
	It's possible that the ebuild has changed the
	CHOST variable, so revert it to the initial
	setting. Also, revert IUSE in case it's corrupted
	due to local environment settings like in bug #386829.
	"""

	eapi_attrs = _get_eapi_attrs(settings.configdict['pkg']['EAPI'])

	build_info_dir = os.path.join(settings['PORTAGE_BUILDDIR'], 'build-info')

	metadata_keys = ['IUSE']
	if eapi_attrs.iuse_effective:
		metadata_keys.append('IUSE_EFFECTIVE')

	for k in metadata_keys:
		v = settings.configdict['pkg'].get(k)
		if v is not None:
			write_atomic(os.path.join(build_info_dir, k), v + '\n')

	# The following variables are irrelevant for virtual packages.
	if settings.get('CATEGORY') != 'virtual':

		for k in ('CHOST',):
			v = settings.get(k)
			if v is not None:
				write_atomic(os.path.join(build_info_dir, k), v + '\n')

	with io.open(_unicode_encode(os.path.join(build_info_dir,
		'BUILD_TIME'), encoding=_encodings['fs'], errors='strict'),
		mode='w', encoding=_encodings['repo.content'],
		errors='strict') as f:
		f.write("%.0f\n" % (time.time(),))

	use = frozenset(settings['PORTAGE_USE'].split())
	for k in _vdb_use_conditional_keys:
		v = settings.configdict['pkg'].get(k)
		filename = os.path.join(build_info_dir, k)
		if v is None:
			try:
				os.unlink(filename)
			except OSError:
				pass
			continue

		if k.endswith('DEPEND'):
			if eapi_attrs.slot_operator:
				continue
			token_class = Atom
		else:
			token_class = None

		v = use_reduce(v, uselist=use, token_class=token_class)
		v = paren_enclose(v)
		if not v:
			try:
				os.unlink(filename)
			except OSError:
				pass
			continue
		with io.open(_unicode_encode(os.path.join(build_info_dir,
			k), encoding=_encodings['fs'], errors='strict'),
			mode='w', encoding=_encodings['repo.content'],
			errors='strict') as f:
			f.write('%s\n' % v)

	if eapi_attrs.slot_operator:
		deps = evaluate_slot_operator_equal_deps(settings, use, QueryCommand.get_db())
		for k, v in deps.items():
			filename = os.path.join(build_info_dir, k)
			if not v:
				try:
					os.unlink(filename)
				except OSError:
					pass
				continue
			with io.open(_unicode_encode(os.path.join(build_info_dir,
				k), encoding=_encodings['fs'], errors='strict'),
				mode='w', encoding=_encodings['repo.content'],
				errors='strict') as f:
				f.write('%s\n' % v)

def _preinst_bsdflags(mysettings):
	if bsd_chflags:
		# Save all the file flags for restoration later.
		os.system("mtree -c -p %s -k flags > %s" % \
			(_shell_quote(mysettings["D"]),
			_shell_quote(os.path.join(mysettings["T"], "bsdflags.mtree"))))

		# Remove all the file flags to avoid EPERM errors.
		os.system("chflags -R noschg,nouchg,nosappnd,nouappnd %s" % \
			(_shell_quote(mysettings["D"]),))
		os.system("chflags -R nosunlnk,nouunlnk %s 2>/dev/null" % \
			(_shell_quote(mysettings["D"]),))


def _postinst_bsdflags(mysettings):
	if bsd_chflags:
		# Restore all of the flags saved above.
		os.system("mtree -e -p %s -U -k flags < %s > /dev/null" % \
			(_shell_quote(mysettings["ROOT"]),
			_shell_quote(os.path.join(mysettings["T"], "bsdflags.mtree"))))

def _post_src_install_uid_fix(mysettings, out):
	"""
	Files in $D with user and group bits that match the "portage"
	user or group are automatically mapped to PORTAGE_INST_UID and
	PORTAGE_INST_GID if necessary. The chown system call may clear
	S_ISUID and S_ISGID bits, so those bits are restored if
	necessary.
	"""

	os = _os_merge

	inst_uid = int(mysettings["PORTAGE_INST_UID"])
	inst_gid = int(mysettings["PORTAGE_INST_GID"])

	_preinst_bsdflags(mysettings)

	destdir = mysettings["D"]
	ed_len = len(mysettings["ED"])
	unicode_errors = []
	desktop_file_validate = \
		portage.process.find_binary("desktop-file-validate") is not None
	xdg_dirs = mysettings.get('XDG_DATA_DIRS', '/usr/share').split(':')
	xdg_dirs = tuple(os.path.join(i, "applications") + os.sep
		for i in xdg_dirs if i)

	qa_desktop_file = ""
	try:
		with io.open(_unicode_encode(os.path.join(
			mysettings["PORTAGE_BUILDDIR"],
			"build-info", "QA_DESKTOP_FILE"),
			encoding=_encodings['fs'], errors='strict'),
			mode='r', encoding=_encodings['repo.content'],
			errors='replace') as f:
			qa_desktop_file = f.read()
	except IOError as e:
		if e.errno not in (errno.ENOENT, errno.ESTALE):
			raise

	qa_desktop_file = qa_desktop_file.split()
	if qa_desktop_file:
		if len(qa_desktop_file) > 1:
			qa_desktop_file = "|".join("(%s)" % x for x in qa_desktop_file)
			qa_desktop_file = "^(%s)$" % qa_desktop_file
		else:
			qa_desktop_file = "^%s$" % qa_desktop_file[0]
		qa_desktop_file = re.compile(qa_desktop_file)

	while True:

		unicode_error = False
		size = 0
		counted_inodes = set()
		fixlafiles_announced = False
		fixlafiles = "fixlafiles" in mysettings.features
		desktopfile_errors = []

		for parent, dirs, files in os.walk(destdir):
			try:
				parent = _unicode_decode(parent,
					encoding=_encodings['merge'], errors='strict')
			except UnicodeDecodeError:
				new_parent = _unicode_decode(parent,
					encoding=_encodings['merge'], errors='replace')
				new_parent = _unicode_encode(new_parent,
					encoding='ascii', errors='backslashreplace')
				new_parent = _unicode_decode(new_parent,
					encoding=_encodings['merge'], errors='replace')
				os.rename(parent, new_parent)
				unicode_error = True
				unicode_errors.append(new_parent[ed_len:])
				break

			for fname in chain(dirs, files):
				try:
					fname = _unicode_decode(fname,
						encoding=_encodings['merge'], errors='strict')
				except UnicodeDecodeError:
					fpath = _os.path.join(
						parent.encode(_encodings['merge']), fname)
					new_fname = _unicode_decode(fname,
						encoding=_encodings['merge'], errors='replace')
					new_fname = _unicode_encode(new_fname,
						encoding='ascii', errors='backslashreplace')
					new_fname = _unicode_decode(new_fname,
						encoding=_encodings['merge'], errors='replace')
					new_fpath = os.path.join(parent, new_fname)
					os.rename(fpath, new_fpath)
					unicode_error = True
					unicode_errors.append(new_fpath[ed_len:])
					fname = new_fname
					fpath = new_fpath
				else:
					fpath = os.path.join(parent, fname)

				fpath_relative = fpath[ed_len - 1:]
				if desktop_file_validate and fname.endswith(".desktop") and \
					os.path.isfile(fpath) and \
					fpath_relative.startswith(xdg_dirs) and \
					not (qa_desktop_file and qa_desktop_file.match(fpath_relative.strip(os.sep)) is not None):

					desktop_validate = validate_desktop_entry(fpath)
					if desktop_validate:
						desktopfile_errors.extend(desktop_validate)

				if fixlafiles and \
					fname.endswith(".la") and os.path.isfile(fpath):
					f = open(_unicode_encode(fpath,
						encoding=_encodings['merge'], errors='strict'),
						mode='rb')
					has_lafile_header = b'.la - a libtool library file' \
						in f.readline()
					f.seek(0)
					contents = f.read()
					f.close()
					try:
						needs_update, new_contents = rewrite_lafile(contents)
					except portage.exception.InvalidData as e:
						needs_update = False
						if not fixlafiles_announced:
							fixlafiles_announced = True
							writemsg("Fixing .la files\n", fd=out)

						# Suppress warnings if the file does not have the
						# expected header (bug #340725). Even if the header is
						# missing, we still call rewrite_lafile() since some
						# valid libtool archives may not have the header.
						msg = "   %s is not a valid libtool archive, skipping\n" % fpath[len(destdir):]
						qa_msg = "QA Notice: invalid .la file found: %s, %s" % (fpath[len(destdir):], e)
						if has_lafile_header:
							writemsg(msg, fd=out)
							eqawarn(qa_msg, key=mysettings.mycpv, out=out)

					if needs_update:
						if not fixlafiles_announced:
							fixlafiles_announced = True
							writemsg("Fixing .la files\n", fd=out)
						writemsg("   %s\n" % fpath[len(destdir):], fd=out)
						# write_atomic succeeds even in some cases in which
						# a normal write might fail due to file permission
						# settings on some operating systems such as HP-UX
						write_atomic(_unicode_encode(fpath,
							encoding=_encodings['merge'], errors='strict'),
							new_contents, mode='wb')

				mystat = os.lstat(fpath)
				if stat.S_ISREG(mystat.st_mode) and \
					mystat.st_ino not in counted_inodes:
					counted_inodes.add(mystat.st_ino)
					size += mystat.st_size
				if mystat.st_uid != portage_uid and \
					mystat.st_gid != portage_gid:
					continue
				myuid = -1
				mygid = -1
				if mystat.st_uid == portage_uid:
					myuid = inst_uid
				if mystat.st_gid == portage_gid:
					mygid = inst_gid
				apply_secpass_permissions(
					_unicode_encode(fpath, encoding=_encodings['merge']),
					uid=myuid, gid=mygid,
					mode=mystat.st_mode, stat_cached=mystat,
					follow_links=False)

			if unicode_error:
				break

		if not unicode_error:
			break

	if desktopfile_errors:
		for l in _merge_desktopfile_error(desktopfile_errors):
			l = l.replace(mysettings["ED"], '/')
			eqawarn(l, phase='install', key=mysettings.mycpv, out=out)

	if unicode_errors:
		for l in _merge_unicode_error(unicode_errors):
			eqawarn(l, phase='install', key=mysettings.mycpv, out=out)

	build_info_dir = os.path.join(mysettings['PORTAGE_BUILDDIR'],
		'build-info')

	f = io.open(_unicode_encode(os.path.join(build_info_dir,
		'SIZE'), encoding=_encodings['fs'], errors='strict'),
		mode='w', encoding=_encodings['repo.content'],
		errors='strict')
	f.write('%d\n' % size)
	f.close()

	_reapply_bsdflags_to_image(mysettings)

def _reapply_bsdflags_to_image(mysettings):
	"""
	Reapply flags saved and removed by _preinst_bsdflags.
	"""
	if bsd_chflags:
		os.system("mtree -e -p %s -U -k flags < %s > /dev/null" % \
			(_shell_quote(mysettings["D"]),
			_shell_quote(os.path.join(mysettings["T"], "bsdflags.mtree"))))

def _post_src_install_soname_symlinks(mysettings, out):
	"""
	Check that libraries in $D have corresponding soname symlinks.
	If symlinks are missing then create them and trigger a QA Notice.
	This requires $PORTAGE_BUILDDIR/build-info/NEEDED.ELF.2 for
	operation.
	"""

	image_dir = mysettings["D"]
	needed_filename = os.path.join(mysettings["PORTAGE_BUILDDIR"],
		"build-info", "NEEDED.ELF.2")

	f = None
	try:
		f = io.open(_unicode_encode(needed_filename,
			encoding=_encodings['fs'], errors='strict'),
			mode='r', encoding=_encodings['repo.content'],
			errors='replace')
		lines = f.readlines()
	except IOError as e:
		if e.errno not in (errno.ENOENT, errno.ESTALE):
			raise
		return
	finally:
		if f is not None:
			f.close()

	qa_no_symlink = ""
	f = None
	try:
		f = io.open(_unicode_encode(os.path.join(
			mysettings["PORTAGE_BUILDDIR"],
			"build-info", "QA_SONAME_NO_SYMLINK"),
			encoding=_encodings['fs'], errors='strict'),
			mode='r', encoding=_encodings['repo.content'],
			errors='replace')
		qa_no_symlink = f.read()
	except IOError as e:
		if e.errno not in (errno.ENOENT, errno.ESTALE):
			raise
	finally:
		if f is not None:
			f.close()

	qa_no_symlink = qa_no_symlink.split()
	if qa_no_symlink:
		if len(qa_no_symlink) > 1:
			qa_no_symlink = "|".join("(%s)" % x for x in qa_no_symlink)
			qa_no_symlink = "^(%s)$" % qa_no_symlink
		else:
			qa_no_symlink = "^%s$" % qa_no_symlink[0]
		qa_no_symlink = re.compile(qa_no_symlink)

	libpaths = set(portage.util.getlibpaths(
		mysettings["ROOT"], env=mysettings))
	libpath_inodes = set()
	for libpath in libpaths:
		libdir = os.path.join(mysettings["ROOT"], libpath.lstrip(os.sep))
		try:
			s = os.stat(libdir)
		except OSError:
			continue
		else:
			libpath_inodes.add((s.st_dev, s.st_ino))

	is_libdir_cache = {}

	def is_libdir(obj_parent):
		try:
			return is_libdir_cache[obj_parent]
		except KeyError:
			pass

		rval = False
		if obj_parent in libpaths:
			rval = True
		else:
			parent_path = os.path.join(mysettings["ROOT"],
				obj_parent.lstrip(os.sep))
			try:
				s = os.stat(parent_path)
			except OSError:
				pass
			else:
				if (s.st_dev, s.st_ino) in libpath_inodes:
					rval = True

		is_libdir_cache[obj_parent] = rval
		return rval

	missing_symlinks = []

	# Parse NEEDED.ELF.2 like LinkageMapELF.rebuild() does.
	for l in lines:
		l = l.rstrip("\n")
		if not l:
			continue
		fields = l.split(";")
		if len(fields) < 5:
			portage.util.writemsg_level(_("\nWrong number of fields " \
				"in %s: %s\n\n") % (needed_filename, l),
				level=logging.ERROR, noiselevel=-1)
			continue

		obj, soname = fields[1:3]
		if not soname:
			continue
		if not is_libdir(os.path.dirname(obj)):
			continue
		if qa_no_symlink and qa_no_symlink.match(obj.strip(os.sep)) is not None:
			continue

		obj_file_path = os.path.join(image_dir, obj.lstrip(os.sep))
		sym_file_path = os.path.join(os.path.dirname(obj_file_path), soname)
		try:
			os.lstat(sym_file_path)
		except OSError as e:
			if e.errno not in (errno.ENOENT, errno.ESTALE):
				raise
		else:
			continue

		missing_symlinks.append((obj, soname))

	if not missing_symlinks:
		return

	qa_msg = ["QA Notice: Missing soname symlink(s):"]
	qa_msg.append("")
	qa_msg.extend("\t%s -> %s" % (os.path.join(
		os.path.dirname(obj).lstrip(os.sep), soname),
		os.path.basename(obj))
		for obj, soname in missing_symlinks)
	qa_msg.append("")
	for line in qa_msg:
		eqawarn(line, key=mysettings.mycpv, out=out)

def _merge_desktopfile_error(errors):
	lines = []

	msg = _("QA Notice: This package installs one or more .desktop files "
		"that do not pass validation.")
	lines.extend(wrap(msg, 72))

	lines.append("")
	errors.sort()
	lines.extend("\t" + x for x in errors)
	lines.append("")

	return lines

def _merge_unicode_error(errors):
	lines = []

	msg = _("QA Notice: This package installs one or more file names "
		"containing characters that are not encoded with the UTF-8 encoding.")
	lines.extend(wrap(msg, 72))

	lines.append("")
	errors.sort()
	lines.extend("\t" + x for x in errors)
	lines.append("")

	return lines

def _prepare_self_update(settings):
	"""
	Call this when portage is updating itself, in order to create
	temporary copies of PORTAGE_BIN_PATH and PORTAGE_PYM_PATH, since
	the new versions may be incompatible. An atexit hook will
	automatically clean up the temporary copies.
	"""

	# sanity check: ensure that that this routine only runs once
	if portage._bin_path != portage.const.PORTAGE_BIN_PATH:
		return

	# Load lazily referenced portage submodules into memory,
	# so imports won't fail during portage upgrade/downgrade.
	_preload_elog_modules(settings)
	portage.proxy.lazyimport._preload_portage_submodules()

	# Make the temp directory inside $PORTAGE_TMPDIR/portage, since
	# it's common for /tmp and /var/tmp to be mounted with the
	# "noexec" option (see bug #346899).
	build_prefix = os.path.join(settings["PORTAGE_TMPDIR"], "portage")
	portage.util.ensure_dirs(build_prefix)
	base_path_tmp = tempfile.mkdtemp(
		"", "._portage_reinstall_.", build_prefix)
	portage.process.atexit_register(shutil.rmtree, base_path_tmp)

	orig_bin_path = portage._bin_path
	portage._bin_path = os.path.join(base_path_tmp, "bin")
	shutil.copytree(orig_bin_path, portage._bin_path, symlinks=True)

	orig_pym_path = portage._pym_path
	portage._pym_path = os.path.join(base_path_tmp, "pym")
	shutil.copytree(orig_pym_path, portage._pym_path, symlinks=True)

	for dir_path in (base_path_tmp, portage._bin_path, portage._pym_path):
		os.chmod(dir_path, 0o755)

def _handle_self_update(settings, vardb):
	cpv = settings.mycpv
	if settings["ROOT"] == "/" and \
		portage.dep.match_from_list(
		portage.const.PORTAGE_PACKAGE_ATOM, [cpv]):
		_prepare_self_update(settings)
		return True
	return False
