diff --git a/nix/overlays/default.nix b/nix/overlays/default.nix index c2a6e5976d..1056e79d2c 100644 --- a/nix/overlays/default.nix +++ b/nix/overlays/default.nix @@ -1,6 +1,6 @@ { self, ... }: { - flake.overlays.default = final: _prev: { + flake.overlays.default = final: prev: { # NOTE: add any needed overlays here. in theory we could # pull them from the overlays/ directory automatically, but we don't # want to have an arbitrary order, since it might matter. being @@ -17,6 +17,11 @@ xmrig = throw "The xmrig package has been explicitly disabled in this flake."; + # Force the pre-2.42 glibc symbol version for cfgetospeed so the portable CLI bundle keeps working on older-glibc hosts. + ncurses = prev.ncurses.overrideAttrs (old: { + patches = (old.patches or [ ]) ++ [ ./patches/ncurses-cfgetospeed-old-glibc-compat.patch ]; + }); + cargo-pgrx = final.callPackage ../cargo-pgrx/default.nix { inherit (final) lib; inherit (final) fetchCrate; diff --git a/nix/overlays/patches/ncurses-cfgetospeed-old-glibc-compat.patch b/nix/overlays/patches/ncurses-cfgetospeed-old-glibc-compat.patch new file mode 100644 index 0000000000..1a1766675c --- /dev/null +++ b/nix/overlays/patches/ncurses-cfgetospeed-old-glibc-compat.patch @@ -0,0 +1,127 @@ +--- a/ncurses/tinfo/lib_baudrate.c 2026-07-31 08:24:24 ++++ b/ncurses/tinfo/lib_baudrate.c 2026-07-31 12:03:39 +@@ -45,6 +45,39 @@ + #endif + + /* ++ * On Linux/glibc, resolve cfgetospeed to the old (functionally identical) ++ * GLIBC_2.17 symbol version at runtime, so binaries built against newer ++ * glibc still run on hosts with older glibc that only export that version. ++ * Done via dlvsym rather than a link-time .symver directive, since the ++ * latter conflicts with ncurses' own --version-script linking. Both dlvsym ++ * and its dlsym fallback are declared directly (rather than via ++ * /_GNU_SOURCE, which may already be locked in by earlier headers ++ * in this file), and neither path calls the bare cfgetospeed identifier, so ++ * no versioned reference to it survives in the compiled output. ++ */ ++#if defined(__linux__) && defined(__GLIBC__) ++extern void *dlvsym(void *handle, const char *symbol, const char *version); ++extern void *dlsym(void *handle, const char *symbol); ++static speed_t ++_supabase_compat_cfgetospeed(const struct termios *t) ++{ ++ static int inited = 0; ++ static speed_t (*fn)(const struct termios *) = NULL; ++ if (!inited) { ++ fn = (speed_t (*)(const struct termios *)) ++ dlvsym((void *) 0, "cfgetospeed", "GLIBC_2.17"); ++ if (!fn) { ++ fn = (speed_t (*)(const struct termios *)) ++ dlsym((void *) 0, "cfgetospeed"); ++ } ++ inited = 1; ++ } ++ return fn ? fn(t) : 0; ++} ++#define cfgetospeed(t) _supabase_compat_cfgetospeed(t) ++#endif ++ ++/* + * These systems use similar header files, which define B1200 as 1200, etc., + * but can be overridden by defining USE_OLD_TTY so B1200 is 9, which makes all + * of the indices up to B115200 fit nicely in a 'short', allowing us to retain +--- a/ncurses/tinfo/tinfo_driver.c 2026-07-31 08:24:24 ++++ b/ncurses/tinfo/tinfo_driver.c 2026-07-31 12:03:50 +@@ -37,6 +37,39 @@ + #include + #include /* ospeed */ + ++/* ++ * On Linux/glibc, resolve cfgetospeed to the old (functionally identical) ++ * GLIBC_2.17 symbol version at runtime, so binaries built against newer ++ * glibc still run on hosts with older glibc that only export that version. ++ * Done via dlvsym rather than a link-time .symver directive, since the ++ * latter conflicts with ncurses' own --version-script linking. Both dlvsym ++ * and its dlsym fallback are declared directly (rather than via ++ * /_GNU_SOURCE, which may already be locked in by earlier headers ++ * in this file), and neither path calls the bare cfgetospeed identifier, so ++ * no versioned reference to it survives in the compiled output. ++ */ ++#if defined(__linux__) && defined(__GLIBC__) ++extern void *dlvsym(void *handle, const char *symbol, const char *version); ++extern void *dlsym(void *handle, const char *symbol); ++static speed_t ++_supabase_compat_cfgetospeed(const struct termios *t) ++{ ++ static int inited = 0; ++ static speed_t (*fn)(const struct termios *) = NULL; ++ if (!inited) { ++ fn = (speed_t (*)(const struct termios *)) ++ dlvsym((void *) 0, "cfgetospeed", "GLIBC_2.17"); ++ if (!fn) { ++ fn = (speed_t (*)(const struct termios *)) ++ dlsym((void *) 0, "cfgetospeed"); ++ } ++ inited = 1; ++ } ++ return fn ? fn(t) : 0; ++} ++#define cfgetospeed(t) _supabase_compat_cfgetospeed(t) ++#endif ++ + #if HAVE_NANOSLEEP + #include + #if HAVE_SYS_TIME_H +--- a/progs/tset.c 2026-07-31 08:24:24 ++++ b/progs/tset.c 2026-07-31 12:03:59 +@@ -89,6 +89,40 @@ + #include + #include + #include ++ ++/* ++ * On Linux/glibc, resolve cfgetospeed to the old (functionally identical) ++ * GLIBC_2.17 symbol version at runtime, so binaries built against newer ++ * glibc still run on hosts with older glibc that only export that version. ++ * Done via dlvsym rather than a link-time .symver directive, since the ++ * latter conflicts with ncurses' own --version-script linking. Both dlvsym ++ * and its dlsym fallback are declared directly (rather than via ++ * /_GNU_SOURCE, which may already be locked in by earlier headers ++ * in this file), and neither path calls the bare cfgetospeed identifier, so ++ * no versioned reference to it survives in the compiled output. ++ */ ++#if defined(__linux__) && defined(__GLIBC__) ++extern void *dlvsym(void *handle, const char *symbol, const char *version); ++extern void *dlsym(void *handle, const char *symbol); ++static speed_t ++_supabase_compat_cfgetospeed(const struct termios *t) ++{ ++ static int inited = 0; ++ static speed_t (*fn)(const struct termios *) = NULL; ++ if (!inited) { ++ fn = (speed_t (*)(const struct termios *)) ++ dlvsym((void *) 0, "cfgetospeed", "GLIBC_2.17"); ++ if (!fn) { ++ fn = (speed_t (*)(const struct termios *)) ++ dlsym((void *) 0, "cfgetospeed"); ++ } ++ inited = 1; ++ } ++ return fn ? fn(t) : 0; ++} ++#define cfgetospeed(t) _supabase_compat_cfgetospeed(t) ++#endif ++ + #include + + #if HAVE_GETTTYNAM