diff options
Diffstat (limited to 'bin/phase-functions.sh')
-rw-r--r-- | bin/phase-functions.sh | 184 |
1 files changed, 184 insertions, 0 deletions
diff --git a/bin/phase-functions.sh b/bin/phase-functions.sh index 383253d5a..f1db257f5 100644 --- a/bin/phase-functions.sh +++ b/bin/phase-functions.sh @@ -2,6 +2,190 @@ # Copyright 1999-2011 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 +# Hardcoded bash lists are needed for backward compatibility with +# <portage-2.1.4 since they assume that a newly installed version +# of ebuild.sh will work for pkg_postinst, pkg_prerm, and pkg_postrm +# when portage is upgrading itself. + +PORTAGE_READONLY_METADATA="DEFINED_PHASES DEPEND DESCRIPTION + EAPI HOMEPAGE INHERITED IUSE REQUIRED_USE KEYWORDS LICENSE + PDEPEND PROVIDE RDEPEND RESTRICT SLOT SRC_URI" + +PORTAGE_READONLY_VARS="D EBUILD EBUILD_PHASE \ + EBUILD_SH_ARGS ECLASSDIR EMERGE_FROM FILESDIR MERGE_TYPE \ + PM_EBUILD_HOOK_DIR \ + PORTAGE_ACTUAL_DISTDIR PORTAGE_ARCHLIST PORTAGE_BASHRC \ + PORTAGE_BINPKG_FILE PORTAGE_BINPKG_TAR_OPTS PORTAGE_BINPKG_TMPFILE \ + PORTAGE_BIN_PATH PORTAGE_BUILDDIR PORTAGE_BUNZIP2_COMMAND \ + PORTAGE_BZIP2_COMMAND PORTAGE_COLORMAP PORTAGE_CONFIGROOT \ + PORTAGE_DEBUG PORTAGE_DEPCACHEDIR PORTAGE_EBUILD_EXIT_FILE \ + PORTAGE_GID PORTAGE_GRPNAME PORTAGE_INST_GID PORTAGE_INST_UID \ + PORTAGE_IPC_DAEMON PORTAGE_IUSE PORTAGE_LOG_FILE \ + PORTAGE_MUTABLE_FILTERED_VARS PORTAGE_PYM_PATH PORTAGE_PYTHON \ + PORTAGE_READONLY_METADATA PORTAGE_READONLY_VARS \ + PORTAGE_REPO_NAME PORTAGE_RESTRICT PORTAGE_SANDBOX_COMPAT_LEVEL \ + PORTAGE_SAVED_READONLY_VARS PORTAGE_SIGPIPE_STATUS \ + PORTAGE_TMPDIR PORTAGE_UPDATE_ENV PORTAGE_USERNAME \ + PORTAGE_VERBOSE PORTAGE_WORKDIR_MODE PORTDIR PORTDIR_OVERLAY \ + PROFILE_PATHS REPLACING_VERSIONS REPLACED_BY_VERSION T WORKDIR" + +PORTAGE_SAVED_READONLY_VARS="A CATEGORY P PF PN PR PV PVR" + +# Variables that portage sets but doesn't mark readonly. +# In order to prevent changed values from causing unexpected +# interference, they are filtered out of the environment when +# it is saved or loaded (any mutations do not persist). +PORTAGE_MUTABLE_FILTERED_VARS="AA HOSTNAME" + +# @FUNCTION: filter_readonly_variables +# @DESCRIPTION: [--filter-sandbox] [--allow-extra-vars] +# Read an environment from stdin and echo to stdout while filtering variables +# with names that are known to cause interference: +# +# * some specific variables for which bash does not allow assignment +# * some specific variables that affect portage or sandbox behavior +# * variable names that begin with a digit or that contain any +# non-alphanumeric characters that are not be supported by bash +# +# --filter-sandbox causes all SANDBOX_* variables to be filtered, which +# is only desired in certain cases, such as during preprocessing or when +# saving environment.bz2 for a binary or installed package. +# +# --filter-features causes the special FEATURES variable to be filtered. +# Generally, we want it to persist between phases since the user might +# want to modify it via bashrc to enable things like splitdebug and +# installsources for specific packages. They should be able to modify it +# in pre_pkg_setup() and have it persist all the way through the install +# phase. However, if FEATURES exist inside environment.bz2 then they +# should be overridden by current settings. +# +# --filter-locale causes locale related variables such as LANG and LC_* +# variables to be filtered. These variables should persist between phases, +# in case they are modified by the ebuild. However, the current user +# settings should be used when loading the environment from a binary or +# installed package. +# +# --filter-path causes the PATH variable to be filtered. This variable +# should persist between phases, in case it is modified by the ebuild. +# However, old settings should be overridden when loading the +# environment from a binary or installed package. +# +# ---allow-extra-vars causes some extra vars to be allowd through, such +# as ${PORTAGE_SAVED_READONLY_VARS} and ${PORTAGE_MUTABLE_FILTERED_VARS}. +# +# In bash-3.2_p20+ an attempt to assign BASH_*, FUNCNAME, GROUPS or any +# readonly variable cause the shell to exit while executing the "source" +# builtin command. To avoid this problem, this function filters those +# variables out and discards them. See bug #190128. +filter_readonly_variables() { + local x filtered_vars + local readonly_bash_vars="BASHOPTS BASHPID DIRSTACK EUID + FUNCNAME GROUPS PIPESTATUS PPID SHELLOPTS UID" + local bash_misc_vars="BASH BASH_.* COMP_WORDBREAKS HISTCMD + HISTFILE HOSTNAME HOSTTYPE IFS LINENO MACHTYPE OLDPWD + OPTERR OPTIND OSTYPE POSIXLY_CORRECT PS4 PWD RANDOM + SECONDS SHELL SHLVL" + local filtered_sandbox_vars="SANDBOX_ACTIVE SANDBOX_BASHRC + SANDBOX_DEBUG_LOG SANDBOX_DISABLED SANDBOX_LIB + SANDBOX_LOG SANDBOX_ON" + local misc_garbage_vars="_portage_filter_opts" + filtered_vars="$readonly_bash_vars $bash_misc_vars + $PORTAGE_READONLY_VARS $misc_garbage_vars" + + # Don't filter/interfere with prefix variables unless they are + # supported by the current EAPI. + case "${EAPI:-0}" in + 0|1|2) + ;; + *) + filtered_vars+=" ED EPREFIX EROOT" + ;; + esac + + if has --filter-sandbox $* ; then + filtered_vars="${filtered_vars} SANDBOX_.*" + else + filtered_vars="${filtered_vars} ${filtered_sandbox_vars}" + fi + if has --filter-features $* ; then + filtered_vars="${filtered_vars} FEATURES PORTAGE_FEATURES" + fi + if has --filter-path $* ; then + filtered_vars+=" PATH" + fi + if has --filter-locale $* ; then + filtered_vars+=" LANG LC_ALL LC_COLLATE + LC_CTYPE LC_MESSAGES LC_MONETARY + LC_NUMERIC LC_PAPER LC_TIME" + fi + if ! has --allow-extra-vars $* ; then + filtered_vars=" + ${filtered_vars} + ${PORTAGE_SAVED_READONLY_VARS} + ${PORTAGE_MUTABLE_FILTERED_VARS} + " + fi + + "${PORTAGE_PYTHON:-/usr/bin/python}" "${PORTAGE_BIN_PATH}"/filter-bash-environment.py "${filtered_vars}" || die "filter-bash-environment.py failed" +} + +# @FUNCTION: preprocess_ebuild_env +# @DESCRIPTION: +# Filter any readonly variables from ${T}/environment, source it, and then +# save it via save_ebuild_env(). This process should be sufficient to prevent +# any stale variables or functions from an arbitrary environment from +# interfering with the current environment. This is useful when an existing +# environment needs to be loaded from a binary or installed package. +preprocess_ebuild_env() { + local _portage_filter_opts="--filter-features --filter-locale --filter-path --filter-sandbox" + + # If environment.raw is present, this is a signal from the python side, + # indicating that the environment may contain stale FEATURES and + # SANDBOX_{DENY,PREDICT,READ,WRITE} variables that should be filtered out. + # Otherwise, we don't need to filter the environment. + [ -f "${T}/environment.raw" ] || return 0 + + filter_readonly_variables $_portage_filter_opts < "${T}"/environment \ + >> "$T/environment.filtered" || return $? + unset _portage_filter_opts + mv "${T}"/environment.filtered "${T}"/environment || return $? + rm -f "${T}/environment.success" || return $? + # WARNING: Code inside this subshell should avoid making assumptions + # about variables or functions after source "${T}"/environment has been + # called. Any variables that need to be relied upon should already be + # filtered out above. + ( + export SANDBOX_ON=1 + source "${T}/environment" || exit $? + # We have to temporarily disable sandbox since the + # SANDBOX_{DENY,READ,PREDICT,WRITE} values we've just loaded + # may be unusable (triggering in spurious sandbox violations) + # until we've merged them with our current values. + export SANDBOX_ON=0 + + # It's remotely possible that save_ebuild_env() has been overridden + # by the above source command. To protect ourselves, we override it + # here with our own version. ${PORTAGE_BIN_PATH} is safe to use here + # because it's already filtered above. + source "${PORTAGE_BIN_PATH}/isolated-functions.sh" || exit $? + + # Rely on save_ebuild_env() to filter out any remaining variables + # and functions that could interfere with the current environment. + save_ebuild_env || exit $? + >> "$T/environment.success" || exit $? + ) > "${T}/environment.filtered" + local retval + if [ -e "${T}/environment.success" ] ; then + filter_readonly_variables --filter-features < \ + "${T}/environment.filtered" > "${T}/environment" + retval=$? + else + retval=1 + fi + rm -f "${T}"/environment.{filtered,raw,success} + return ${retval} +} + ebuild_phase() { declare -F "$1" >/dev/null && qa_call $1 } |