Skip to content

Commit

Permalink
Do not export A in EAPI 9
Browse files Browse the repository at this point in the history
Instead of passing A as part of the process environment, we pass it
via a file. Since A is usually the greatest contributor to the process
environment, removing it from the process environment significantly
avoids running into MAX_ARG_STRLEN when spawning a new child process.

This means that A is no longer exported in the ebuild and hence
unavaiable to child processes. However, A is mostly used as part of
the default_src_unpack function and there A does not need to be
exported.

Thanks to Zac Medico for helpful input on this change.

Closes: https://bugs.gentoo.org/721088
Signed-off-by: Florian Schmaus <[email protected]>
  • Loading branch information
Flowdalic committed Dec 30, 2024
1 parent 6f958be commit 9f93e30
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 3 deletions.
7 changes: 6 additions & 1 deletion bin/ebuild.sh
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#!/usr/bin/env bash
# Copyright 1999-2021 Gentoo Authors
# Copyright 1999-2024 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2

# Prevent aliases from causing portage to act inappropriately.
Expand All @@ -10,6 +10,11 @@ unalias -a
unset BASH_COMPAT
declare -F ___in_portage_iuse >/dev/null && export -n -f ___in_portage_iuse

if [[ -v PORTAGE_EBUILD_EXTRA_SOURCE ]]; then
source "${PORTAGE_EBUILD_EXTRA_SOURCE}" || exit 1
unset PORTAGE_EBUILD_EXTRA_SOURCE
fi

source "${PORTAGE_BIN_PATH}/isolated-functions.sh" || exit 1

# Set up the bash version compatibility level. This does not disable
Expand Down
1 change: 1 addition & 0 deletions lib/portage/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,7 @@
"digest",
"distcc",
"distlocks",
"dont-export-a",
"downgrade-backup",
"ebuild-locks",
"fail-clean",
Expand Down
10 changes: 9 additions & 1 deletion lib/portage/eapi.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Copyright 2010-2021 Gentoo Authors
# Copyright 2010-2024 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2

import collections
Expand Down Expand Up @@ -48,6 +48,10 @@ def eapi_supports_prefix(eapi: str) -> bool:
return _get_eapi_attrs(eapi).prefix


def eapi_exports_A(eapi: str) -> bool:
return _get_eapi_attrs(eapi).exports_A


def eapi_exports_AA(eapi: str) -> bool:
return _get_eapi_attrs(eapi).exports_AA

Expand Down Expand Up @@ -152,6 +156,7 @@ def eapi_has_sysroot(eapi: str) -> bool:
"broot",
"dosed_dohard",
"empty_groups_always_true",
"exports_A",
"exports_AA",
"exports_EBUILD_PHASE_FUNC",
"exports_ECLASSDIR",
Expand Down Expand Up @@ -198,6 +203,7 @@ class Eapi:
"6",
"7",
"8",
"9",
)

_eapi_val: int = -1
Expand Down Expand Up @@ -231,6 +237,7 @@ def _get_eapi_attrs(eapi_str: Optional[str]) -> _eapi_attrs:
broot=True,
dosed_dohard=False,
empty_groups_always_true=False,
exports_A=True,
exports_AA=False,
exports_EBUILD_PHASE_FUNC=True,
exports_ECLASSDIR=False,
Expand Down Expand Up @@ -270,6 +277,7 @@ def _get_eapi_attrs(eapi_str: Optional[str]) -> _eapi_attrs:
broot=eapi >= Eapi("7"),
dosed_dohard=eapi <= Eapi("3"),
empty_groups_always_true=eapi <= Eapi("6"),
exports_A=eapi <= Eapi("8"),
exports_AA=eapi <= Eapi("3"),
exports_EBUILD_PHASE_FUNC=eapi >= Eapi("5"),
exports_ECLASSDIR=eapi <= Eapi("6"),
Expand Down
31 changes: 30 additions & 1 deletion lib/portage/package/ebuild/doebuild.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@
)
from portage.dep.libc import find_libc_deps
from portage.eapi import (
eapi_exports_A,
eapi_exports_KV,
eapi_exports_merge_type,
eapi_exports_replace_vars,
Expand Down Expand Up @@ -2133,9 +2134,37 @@ def spawn(
logname_backup = mysettings.configdict["env"].get("LOGNAME")
mysettings.configdict["env"]["LOGNAME"] = logname

eapi = mysettings["EAPI"]

unexported_env_vars = set()
if "dont-export-a" in mysettings.features or not eapi_exports_A(eapi):
unexported_env_vars.add("A")

if unexported_env_vars:
orig_env = mysettings.environ()
# Copy since we are potentially removing keys from the dict.
env = orig_env.copy()

t = env["T"]
if not os.path.isdir(t):
os.makedirs(t)

ebuildExtraSource = os.path.join(t, "portage-ebuild-extra-source")
with open(ebuildExtraSource, mode="w") as f:
for var_name in unexported_env_vars:
var_value = orig_env.get(var_name)
if var_value is None:
continue
f.write(f"{var_name}='{var_value}'\n")
del env[var_name]

env["PORTAGE_EBUILD_EXTRA_SOURCE"] = str(ebuildExtraSource)
else:
env = mysettings.environ()

try:
if keywords.get("returnpid") or keywords.get("returnproc"):
return spawn_func(mystring, env=mysettings.environ(), **keywords)
return spawn_func(mystring, env=env, **keywords)

proc = EbuildSpawnProcess(
background=False,
Expand Down

0 comments on commit 9f93e30

Please sign in to comment.