From e74b9d53df886c9c03b89edb57a094354f09f35b Mon Sep 17 00:00:00 2001 From: ridiculousfish Date: Mon, 31 May 2021 12:45:40 -0700 Subject: [PATCH] Do not use posix_spawn on glibc < 2.24 This concerns the behavior of posix_spawn for shebangless scripts. At some point, glibc started executing them using `sh`, which is desirable for fish's shebangless support (see #7802). On glibcs without that behavior the shebangless test fails. So this change disables posix_spawn on older glibcs. It's not easy to figure out when that happened but it definitely happens in glibc 2.28, and does not happen in glibc 2.17. Presumably the new behavior is present in glibc 2.24 (see BZ#23264) so that's the cutoff: posix_spawn is no longer allowed on glibc < 2.24. This fixes the noshebang test failures on Ubuntu Xenial and Centos 7. See discussion at bottom of #8021. --- src/env_dispatch.cpp | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/src/env_dispatch.cpp b/src/env_dispatch.cpp index 21c846c0c..d7e150682 100644 --- a/src/env_dispatch.cpp +++ b/src/env_dispatch.cpp @@ -265,9 +265,27 @@ static relaxed_atomic_bool_t g_use_posix_spawn{false}; bool get_use_posix_spawn() { return g_use_posix_spawn; } +extern "C" { +const char *gnu_get_libc_version(); +} + +// Disallow posix_spawn entirely on glibc <= 2.24. +// See #8021. +static bool allow_use_posix_spawn() { + bool result = true; + // uClibc defines __GLIBC__. +#if defined(__GLIBC__) && !defined(__UCLIBC__) + const char *version = gnu_get_libc_version(); + result = version && strtod(version, nullptr) >= 2.24; +#endif + return result; +} + static void handle_fish_use_posix_spawn_change(const environment_t &vars) { // Note if the variable is missing or empty, we default to true. - if (auto var = vars.get(L"fish_use_posix_spawn")) { + if (!allow_use_posix_spawn()) { + g_use_posix_spawn = false; + } else if (auto var = vars.get(L"fish_use_posix_spawn")) { g_use_posix_spawn = var->empty() || bool_from_string(var->as_string()); } else { g_use_posix_spawn = true;