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.
This commit is contained in:
ridiculousfish 2021-05-31 12:45:40 -07:00
parent 50c851d10e
commit e74b9d53df

View File

@ -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;