Python-checkins
Threads by month
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2005 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2004 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2003 -----
- December
- November
- October
- September
- August
July 2024
- 1 participants
- 753 discussions
gh-113565: Improve and harden detection of curses dependencies (#119816)
by erlend-aasland July 1, 2024
by erlend-aasland July 1, 2024
July 1, 2024
https://github.com/python/cpython/commit/f80376b129ad947263a6b03a6c3a874e9f…
commit: f80376b129ad947263a6b03a6c3a874e9f8706e6
branch: main
author: Erlend E. Aasland <erlend(a)python.org>
committer: erlend-aasland <erlend.aasland(a)protonmail.com>
date: 2024-07-01T08:10:03Z
summary:
gh-113565: Improve and harden detection of curses dependencies (#119816)
1. Use pkg-config to check for ncursesw/panelw. If that fails, use
pkg-config to check for ncurses/panel.
2. Regardless of pkg-config output, search for curses/panel headers, so
we're sure we have all defines in pyconfig.h.
3. Regardless of pkg-config output, check if libncurses or libncursesw
contains the 'initscr' symbol; if it does _and_ pkg-config failed
earlier, add the resulting -llib linker option to CURSES_LIBS.
Ditto for 'update_panels' and PANEL_LIBS.
4. Wrap the rest of the checks with WITH_SAVE_ENV and make sure we're
using updated LIBS and CPPFLAGS for those.
Add the PY_CHECK_CURSES convenience macro.
files:
A Misc/NEWS.d/next/Build/2024-06-02-13-23-26.gh-issue-113565.8xBlId.rst
M Include/py_curses.h
M Modules/_curses_panel.c
M Modules/_cursesmodule.c
M configure
M configure.ac
M pyconfig.h.in
diff --git a/Include/py_curses.h b/Include/py_curses.h
index a51d9980eee401..79b1b01fcfa594 100644
--- a/Include/py_curses.h
+++ b/Include/py_curses.h
@@ -36,13 +36,21 @@
#define NCURSES_OPAQUE 0
#endif
-#ifdef HAVE_NCURSES_H
-#include <ncurses.h>
-#else
-#include <curses.h>
+#if defined(HAVE_NCURSESW_NCURSES_H)
+# include <ncursesw/ncurses.h>
+#elif defined(HAVE_NCURSESW_CURSES_H)
+# include <ncursesw/curses.h>
+#elif defined(HAVE_NCURSES_NCURSES_H)
+# include <ncurses/ncurses.h>
+#elif defined(HAVE_NCURSES_CURSES_H)
+# include <ncurses/curses.h>
+#elif defined(HAVE_NCURSES_H)
+# include <ncurses.h>
+#elif defined(HAVE_CURSES_H)
+# include <curses.h>
#endif
-#ifdef HAVE_NCURSES_H
+#ifdef NCURSES_VERSION
/* configure was checking <curses.h>, but we will
use <ncurses.h>, which has some or all these features. */
#if !defined(WINDOW_HAS_FLAGS) && \
diff --git a/Misc/NEWS.d/next/Build/2024-06-02-13-23-26.gh-issue-113565.8xBlId.rst b/Misc/NEWS.d/next/Build/2024-06-02-13-23-26.gh-issue-113565.8xBlId.rst
new file mode 100644
index 00000000000000..e26509cd434110
--- /dev/null
+++ b/Misc/NEWS.d/next/Build/2024-06-02-13-23-26.gh-issue-113565.8xBlId.rst
@@ -0,0 +1,2 @@
+Improve :mod:`curses` and :mod:`curses.panel` dependency checks in
+:program:`configure`.
diff --git a/Modules/_curses_panel.c b/Modules/_curses_panel.c
index 125c72dbbe7712..bbbb62c9066df0 100644
--- a/Modules/_curses_panel.c
+++ b/Modules/_curses_panel.c
@@ -19,7 +19,13 @@ static const char PyCursesVersion[] = "2.1";
#include "py_curses.h"
-#include <panel.h>
+#if defined(HAVE_NCURSESW_PANEL_H)
+# include <ncursesw/panel.h>
+#elif defined(HAVE_NCURSES_PANEL_H)
+# include <ncurses/panel.h>
+#elif defined(HAVE_PANEL_H)
+# include <panel.h>
+#endif
typedef struct {
PyObject *PyCursesError;
diff --git a/Modules/_cursesmodule.c b/Modules/_cursesmodule.c
index 3a011963968b1a..b5854e8c33f28a 100644
--- a/Modules/_cursesmodule.c
+++ b/Modules/_cursesmodule.c
@@ -128,7 +128,7 @@ static const char PyCursesVersion[] = "2.2";
#include <langinfo.h>
#endif
-#if !defined(HAVE_NCURSES_H) && (defined(sgi) || defined(__sun) || defined(SCO5))
+#if !defined(NCURSES_VERSION) && (defined(sgi) || defined(__sun) || defined(SCO5))
#define STRICT_SYSV_CURSES /* Don't use ncurses extensions */
typedef chtype attr_t; /* No attr_t type is available */
#endif
diff --git a/configure b/configure
index 99d86437327a01..963ceb9ae38041 100755
--- a/configure
+++ b/configure
@@ -26081,24 +26081,10 @@ have_curses=no
have_panel=no
-ac_fn_c_check_header_compile "$LINENO" "curses.h" "ac_cv_header_curses_h" "$ac_includes_default"
-if test "x$ac_cv_header_curses_h" = xyes
-then :
- printf "%s\n" "#define HAVE_CURSES_H 1" >>confdefs.h
-
-fi
-ac_fn_c_check_header_compile "$LINENO" "ncurses.h" "ac_cv_header_ncurses_h" "$ac_includes_default"
-if test "x$ac_cv_header_ncurses_h" = xyes
-then :
- printf "%s\n" "#define HAVE_NCURSES_H 1" >>confdefs.h
-
-fi
+# Check for ncursesw/panelw first. If that fails, try ncurses/panel.
-if test "x$ac_cv_header_ncurses_h" = xyes
-then :
- if test "$ac_sys_system" != "Darwin"; then
pkg_failed=no
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for ncursesw" >&5
@@ -26158,382 +26144,20 @@ fi
# Put the nasty error message in config.log where it belongs
echo "$CURSES_PKG_ERRORS" >&5
-
- save_CFLAGS=$CFLAGS
-save_CPPFLAGS=$CPPFLAGS
-save_LDFLAGS=$LDFLAGS
-save_LIBS=$LIBS
-
-
- { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for initscr in -lncursesw" >&5
-printf %s "checking for initscr in -lncursesw... " >&6; }
-if test ${ac_cv_lib_ncursesw_initscr+y}
-then :
- printf %s "(cached) " >&6
-else $as_nop
- ac_check_lib_save_LIBS=$LIBS
-LIBS="-lncursesw $LIBS"
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-/* Override any GCC internal prototype to avoid an error.
- Use char because int might match the return type of a GCC
- builtin and then its argument prototype would still apply. */
-char initscr ();
-int
-main (void)
-{
-return initscr ();
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"
-then :
- ac_cv_lib_ncursesw_initscr=yes
-else $as_nop
- ac_cv_lib_ncursesw_initscr=no
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.beam \
- conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ncursesw_initscr" >&5
-printf "%s\n" "$ac_cv_lib_ncursesw_initscr" >&6; }
-if test "x$ac_cv_lib_ncursesw_initscr" = xyes
-then :
-
- printf "%s\n" "#define HAVE_NCURSESW 1" >>confdefs.h
-
- have_curses=ncursesw
- CURSES_CFLAGS=${CURSES_CFLAGS-""}
- CURSES_LIBS=${CURSES_LIBS-"-lncursesw"}
-
-fi
-
-
-CFLAGS=$save_CFLAGS
-CPPFLAGS=$save_CPPFLAGS
-LDFLAGS=$save_LDFLAGS
-LIBS=$save_LIBS
-
-
-
+ have_curses=no
elif test $pkg_failed = untried; then
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
printf "%s\n" "no" >&6; }
-
- save_CFLAGS=$CFLAGS
-save_CPPFLAGS=$CPPFLAGS
-save_LDFLAGS=$LDFLAGS
-save_LIBS=$LIBS
-
-
- { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for initscr in -lncursesw" >&5
-printf %s "checking for initscr in -lncursesw... " >&6; }
-if test ${ac_cv_lib_ncursesw_initscr+y}
-then :
- printf %s "(cached) " >&6
-else $as_nop
- ac_check_lib_save_LIBS=$LIBS
-LIBS="-lncursesw $LIBS"
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-/* Override any GCC internal prototype to avoid an error.
- Use char because int might match the return type of a GCC
- builtin and then its argument prototype would still apply. */
-char initscr ();
-int
-main (void)
-{
-return initscr ();
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"
-then :
- ac_cv_lib_ncursesw_initscr=yes
-else $as_nop
- ac_cv_lib_ncursesw_initscr=no
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.beam \
- conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ncursesw_initscr" >&5
-printf "%s\n" "$ac_cv_lib_ncursesw_initscr" >&6; }
-if test "x$ac_cv_lib_ncursesw_initscr" = xyes
-then :
-
- printf "%s\n" "#define HAVE_NCURSESW 1" >>confdefs.h
-
- have_curses=ncursesw
- CURSES_CFLAGS=${CURSES_CFLAGS-""}
- CURSES_LIBS=${CURSES_LIBS-"-lncursesw"}
-
-fi
-
-
-CFLAGS=$save_CFLAGS
-CPPFLAGS=$save_CPPFLAGS
-LDFLAGS=$save_LDFLAGS
-LIBS=$save_LIBS
-
-
-
+ have_curses=no
else
CURSES_CFLAGS=$pkg_cv_CURSES_CFLAGS
CURSES_LIBS=$pkg_cv_CURSES_LIBS
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
printf "%s\n" "yes" >&6; }
- printf "%s\n" "#define HAVE_NCURSESW 1" >>confdefs.h
-
- have_curses=ncursesw
-
-fi
- fi
-
- if test "x$have_curses" = xno
-then :
-
-
-pkg_failed=no
-{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for ncurses" >&5
-printf %s "checking for ncurses... " >&6; }
-
-if test -n "$CURSES_CFLAGS"; then
- pkg_cv_CURSES_CFLAGS="$CURSES_CFLAGS"
- elif test -n "$PKG_CONFIG"; then
- if test -n "$PKG_CONFIG" && \
- { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"ncurses\""; } >&5
- ($PKG_CONFIG --exists --print-errors "ncurses") 2>&5
- ac_status=$?
- printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; }; then
- pkg_cv_CURSES_CFLAGS=`$PKG_CONFIG --cflags "ncurses" 2>/dev/null`
- test "x$?" != "x0" && pkg_failed=yes
-else
- pkg_failed=yes
-fi
- else
- pkg_failed=untried
-fi
-if test -n "$CURSES_LIBS"; then
- pkg_cv_CURSES_LIBS="$CURSES_LIBS"
- elif test -n "$PKG_CONFIG"; then
- if test -n "$PKG_CONFIG" && \
- { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"ncurses\""; } >&5
- ($PKG_CONFIG --exists --print-errors "ncurses") 2>&5
- ac_status=$?
- printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; }; then
- pkg_cv_CURSES_LIBS=`$PKG_CONFIG --libs "ncurses" 2>/dev/null`
- test "x$?" != "x0" && pkg_failed=yes
-else
- pkg_failed=yes
-fi
- else
- pkg_failed=untried
-fi
-
-
-
-if test $pkg_failed = yes; then
- { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
-printf "%s\n" "no" >&6; }
-
-if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
- _pkg_short_errors_supported=yes
-else
- _pkg_short_errors_supported=no
-fi
- if test $_pkg_short_errors_supported = yes; then
- CURSES_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "ncurses" 2>&1`
- else
- CURSES_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "ncurses" 2>&1`
- fi
- # Put the nasty error message in config.log where it belongs
- echo "$CURSES_PKG_ERRORS" >&5
-
-
- save_CFLAGS=$CFLAGS
-save_CPPFLAGS=$CPPFLAGS
-save_LDFLAGS=$LDFLAGS
-save_LIBS=$LIBS
-
-
- { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for initscr in -lncurses" >&5
-printf %s "checking for initscr in -lncurses... " >&6; }
-if test ${ac_cv_lib_ncurses_initscr+y}
-then :
- printf %s "(cached) " >&6
-else $as_nop
- ac_check_lib_save_LIBS=$LIBS
-LIBS="-lncurses $LIBS"
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-/* Override any GCC internal prototype to avoid an error.
- Use char because int might match the return type of a GCC
- builtin and then its argument prototype would still apply. */
-char initscr ();
-int
-main (void)
-{
-return initscr ();
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"
-then :
- ac_cv_lib_ncurses_initscr=yes
-else $as_nop
- ac_cv_lib_ncurses_initscr=no
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.beam \
- conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ncurses_initscr" >&5
-printf "%s\n" "$ac_cv_lib_ncurses_initscr" >&6; }
-if test "x$ac_cv_lib_ncurses_initscr" = xyes
-then :
-
- have_curses=ncurses
- CURSES_CFLAGS=${CURSES_CFLAGS-""}
- CURSES_LIBS=${CURSES_LIBS-"-lncurses"}
-
-fi
-
-
-CFLAGS=$save_CFLAGS
-CPPFLAGS=$save_CPPFLAGS
-LDFLAGS=$save_LDFLAGS
-LIBS=$save_LIBS
-
-
-
-elif test $pkg_failed = untried; then
- { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
-printf "%s\n" "no" >&6; }
-
- save_CFLAGS=$CFLAGS
-save_CPPFLAGS=$CPPFLAGS
-save_LDFLAGS=$LDFLAGS
-save_LIBS=$LIBS
-
-
- { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for initscr in -lncurses" >&5
-printf %s "checking for initscr in -lncurses... " >&6; }
-if test ${ac_cv_lib_ncurses_initscr+y}
-then :
- printf %s "(cached) " >&6
-else $as_nop
- ac_check_lib_save_LIBS=$LIBS
-LIBS="-lncurses $LIBS"
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-/* Override any GCC internal prototype to avoid an error.
- Use char because int might match the return type of a GCC
- builtin and then its argument prototype would still apply. */
-char initscr ();
-int
-main (void)
-{
-return initscr ();
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"
-then :
- ac_cv_lib_ncurses_initscr=yes
-else $as_nop
- ac_cv_lib_ncurses_initscr=no
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.beam \
- conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ncurses_initscr" >&5
-printf "%s\n" "$ac_cv_lib_ncurses_initscr" >&6; }
-if test "x$ac_cv_lib_ncurses_initscr" = xyes
-then :
-
- have_curses=ncurses
- CURSES_CFLAGS=${CURSES_CFLAGS-""}
- CURSES_LIBS=${CURSES_LIBS-"-lncurses"}
-
-fi
-
-
-CFLAGS=$save_CFLAGS
-CPPFLAGS=$save_CPPFLAGS
-LDFLAGS=$save_LDFLAGS
-LIBS=$save_LIBS
-
-
-
-else
- CURSES_CFLAGS=$pkg_cv_CURSES_CFLAGS
- CURSES_LIBS=$pkg_cv_CURSES_LIBS
- { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-printf "%s\n" "yes" >&6; }
-
- have_curses=ncurses
-
-fi
-
-fi
-
-
-fi
-CURSES_CFLAGS=$(echo $CURSES_CFLAGS | sed 's/-D_XOPEN_SOURCE=600//g')
-
-if test "$have_curses" != no -a "$ac_sys_system" = "Darwin"; then
-
- as_fn_append CURSES_CFLAGS " -D_XOPEN_SOURCE_EXTENDED=1"
- printf "%s\n" "#define HAVE_NCURSESW 1" >>confdefs.h
-
-fi
-
-
-{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking curses module flags" >&5
-printf %s "checking curses module flags... " >&6; }
-if test "x$have_curses" = xno
-then :
-
- { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
-printf "%s\n" "no" >&6; }
-
-else $as_nop
-
- { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $have_curses (CFLAGS: $CURSES_CFLAGS, LIBS: $CURSES_LIBS)" >&5
-printf "%s\n" "$have_curses (CFLAGS: $CURSES_CFLAGS, LIBS: $CURSES_LIBS)" >&6; }
-
-fi
-
-ac_fn_c_check_header_compile "$LINENO" "panel.h" "ac_cv_header_panel_h" "$ac_includes_default"
-if test "x$ac_cv_header_panel_h" = xyes
-then :
- printf "%s\n" "#define HAVE_PANEL_H 1" >>confdefs.h
-
-fi
-
-
-if test "x$ac_cv_header_panel_h" = xyes
-then :
-
-
- if test "$ac_sys_system" != "Darwin"; then
- if test "x$have_curses" = xncursesw
-then :
+printf "%s\n" "#define HAVE_NCURSESW 1" >>confdefs.h
+ have_curses=yes
pkg_failed=no
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for panelw" >&5
@@ -26593,143 +26217,101 @@ fi
# Put the nasty error message in config.log where it belongs
echo "$PANEL_PKG_ERRORS" >&5
+ have_panel=no
+elif test $pkg_failed = untried; then
+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
+ have_panel=no
+else
+ PANEL_CFLAGS=$pkg_cv_PANEL_CFLAGS
+ PANEL_LIBS=$pkg_cv_PANEL_LIBS
+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+printf "%s\n" "yes" >&6; }
- save_CFLAGS=$CFLAGS
-save_CPPFLAGS=$CPPFLAGS
-save_LDFLAGS=$LDFLAGS
-save_LIBS=$LIBS
-
-
- { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for update_panels in -lpanelw" >&5
-printf %s "checking for update_panels in -lpanelw... " >&6; }
-if test ${ac_cv_lib_panelw_update_panels+y}
-then :
- printf %s "(cached) " >&6
-else $as_nop
- ac_check_lib_save_LIBS=$LIBS
-LIBS="-lpanelw $LIBS"
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
+printf "%s\n" "#define HAVE_PANELW 1" >>confdefs.h
-/* Override any GCC internal prototype to avoid an error.
- Use char because int might match the return type of a GCC
- builtin and then its argument prototype would still apply. */
-char update_panels ();
-int
-main (void)
-{
-return update_panels ();
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"
-then :
- ac_cv_lib_panelw_update_panels=yes
-else $as_nop
- ac_cv_lib_panelw_update_panels=no
+ have_panel=yes
fi
-rm -f core conftest.err conftest.$ac_objext conftest.beam \
- conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
fi
-{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_panelw_update_panels" >&5
-printf "%s\n" "$ac_cv_lib_panelw_update_panels" >&6; }
-if test "x$ac_cv_lib_panelw_update_panels" = xyes
-then :
- have_panel=panelw
- PANEL_CFLAGS=${PANEL_CFLAGS-""}
- PANEL_LIBS=${PANEL_LIBS-"-lpanelw"}
-fi
-
-
-CFLAGS=$save_CFLAGS
-CPPFLAGS=$save_CPPFLAGS
-LDFLAGS=$save_LDFLAGS
-LIBS=$save_LIBS
-
-
-
-elif test $pkg_failed = untried; then
- { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
-printf "%s\n" "no" >&6; }
+if test "x$have_curses" = xno
+then :
- save_CFLAGS=$CFLAGS
-save_CPPFLAGS=$CPPFLAGS
-save_LDFLAGS=$LDFLAGS
-save_LIBS=$LIBS
- { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for update_panels in -lpanelw" >&5
-printf %s "checking for update_panels in -lpanelw... " >&6; }
-if test ${ac_cv_lib_panelw_update_panels+y}
-then :
- printf %s "(cached) " >&6
-else $as_nop
- ac_check_lib_save_LIBS=$LIBS
-LIBS="-lpanelw $LIBS"
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
+pkg_failed=no
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for ncurses" >&5
+printf %s "checking for ncurses... " >&6; }
-/* Override any GCC internal prototype to avoid an error.
- Use char because int might match the return type of a GCC
- builtin and then its argument prototype would still apply. */
-char update_panels ();
-int
-main (void)
-{
-return update_panels ();
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"
-then :
- ac_cv_lib_panelw_update_panels=yes
-else $as_nop
- ac_cv_lib_panelw_update_panels=no
+if test -n "$CURSES_CFLAGS"; then
+ pkg_cv_CURSES_CFLAGS="$CURSES_CFLAGS"
+ elif test -n "$PKG_CONFIG"; then
+ if test -n "$PKG_CONFIG" && \
+ { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"ncurses\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "ncurses") 2>&5
+ ac_status=$?
+ printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ pkg_cv_CURSES_CFLAGS=`$PKG_CONFIG --cflags "ncurses" 2>/dev/null`
+ test "x$?" != "x0" && pkg_failed=yes
+else
+ pkg_failed=yes
fi
-rm -f core conftest.err conftest.$ac_objext conftest.beam \
- conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
+ else
+ pkg_failed=untried
fi
-{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_panelw_update_panels" >&5
-printf "%s\n" "$ac_cv_lib_panelw_update_panels" >&6; }
-if test "x$ac_cv_lib_panelw_update_panels" = xyes
-then :
-
- have_panel=panelw
- PANEL_CFLAGS=${PANEL_CFLAGS-""}
- PANEL_LIBS=${PANEL_LIBS-"-lpanelw"}
-
+if test -n "$CURSES_LIBS"; then
+ pkg_cv_CURSES_LIBS="$CURSES_LIBS"
+ elif test -n "$PKG_CONFIG"; then
+ if test -n "$PKG_CONFIG" && \
+ { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"ncurses\""; } >&5
+ ($PKG_CONFIG --exists --print-errors "ncurses") 2>&5
+ ac_status=$?
+ printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ pkg_cv_CURSES_LIBS=`$PKG_CONFIG --libs "ncurses" 2>/dev/null`
+ test "x$?" != "x0" && pkg_failed=yes
+else
+ pkg_failed=yes
+fi
+ else
+ pkg_failed=untried
fi
-CFLAGS=$save_CFLAGS
-CPPFLAGS=$save_CPPFLAGS
-LDFLAGS=$save_LDFLAGS
-LIBS=$save_LIBS
+if test $pkg_failed = yes; then
+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
+if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
+ _pkg_short_errors_supported=yes
+else
+ _pkg_short_errors_supported=no
+fi
+ if test $_pkg_short_errors_supported = yes; then
+ CURSES_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "ncurses" 2>&1`
+ else
+ CURSES_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "ncurses" 2>&1`
+ fi
+ # Put the nasty error message in config.log where it belongs
+ echo "$CURSES_PKG_ERRORS" >&5
+ have_curses=no
+elif test $pkg_failed = untried; then
+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
+ have_curses=no
else
- PANEL_CFLAGS=$pkg_cv_PANEL_CFLAGS
- PANEL_LIBS=$pkg_cv_PANEL_LIBS
+ CURSES_CFLAGS=$pkg_cv_CURSES_CFLAGS
+ CURSES_LIBS=$pkg_cv_CURSES_LIBS
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
printf "%s\n" "yes" >&6; }
- have_panel=panelw
-
-fi
-
-fi
- fi
-
- if test "x$have_curses" = xncurses
-then :
+printf "%s\n" "#define HAVE_NCURSES 1" >>confdefs.h
+ have_curses=yes
pkg_failed=no
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for panel" >&5
@@ -26789,83 +26371,165 @@ fi
# Put the nasty error message in config.log where it belongs
echo "$PANEL_PKG_ERRORS" >&5
+ have_panel=no
+elif test $pkg_failed = untried; then
+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
+ have_panel=no
+else
+ PANEL_CFLAGS=$pkg_cv_PANEL_CFLAGS
+ PANEL_LIBS=$pkg_cv_PANEL_LIBS
+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+printf "%s\n" "yes" >&6; }
+
+printf "%s\n" "#define HAVE_PANEL 1" >>confdefs.h
- save_CFLAGS=$CFLAGS
+ have_panel=yes
+fi
+fi
+
+
+fi
+
+save_CFLAGS=$CFLAGS
save_CPPFLAGS=$CPPFLAGS
save_LDFLAGS=$LDFLAGS
save_LIBS=$LIBS
- { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for update_panels in -lpanel" >&5
-printf %s "checking for update_panels in -lpanel... " >&6; }
-if test ${ac_cv_lib_panel_update_panels+y}
+ # Make sure we've got the header defines.
+ as_fn_append CPPFLAGS " $CURSES_CFLAGS $PANEL_CFLAGS"
+ ac_fn_c_check_header_compile "$LINENO" "ncursesw/curses.h" "ac_cv_header_ncursesw_curses_h" "$ac_includes_default"
+if test "x$ac_cv_header_ncursesw_curses_h" = xyes
+then :
+ printf "%s\n" "#define HAVE_NCURSESW_CURSES_H 1" >>confdefs.h
+
+fi
+ac_fn_c_check_header_compile "$LINENO" "ncursesw/ncurses.h" "ac_cv_header_ncursesw_ncurses_h" "$ac_includes_default"
+if test "x$ac_cv_header_ncursesw_ncurses_h" = xyes
+then :
+ printf "%s\n" "#define HAVE_NCURSESW_NCURSES_H 1" >>confdefs.h
+
+fi
+ac_fn_c_check_header_compile "$LINENO" "ncursesw/panel.h" "ac_cv_header_ncursesw_panel_h" "$ac_includes_default"
+if test "x$ac_cv_header_ncursesw_panel_h" = xyes
+then :
+ printf "%s\n" "#define HAVE_NCURSESW_PANEL_H 1" >>confdefs.h
+
+fi
+ac_fn_c_check_header_compile "$LINENO" "ncurses/curses.h" "ac_cv_header_ncurses_curses_h" "$ac_includes_default"
+if test "x$ac_cv_header_ncurses_curses_h" = xyes
+then :
+ printf "%s\n" "#define HAVE_NCURSES_CURSES_H 1" >>confdefs.h
+
+fi
+ac_fn_c_check_header_compile "$LINENO" "ncurses/ncurses.h" "ac_cv_header_ncurses_ncurses_h" "$ac_includes_default"
+if test "x$ac_cv_header_ncurses_ncurses_h" = xyes
+then :
+ printf "%s\n" "#define HAVE_NCURSES_NCURSES_H 1" >>confdefs.h
+
+fi
+ac_fn_c_check_header_compile "$LINENO" "ncurses/panel.h" "ac_cv_header_ncurses_panel_h" "$ac_includes_default"
+if test "x$ac_cv_header_ncurses_panel_h" = xyes
+then :
+ printf "%s\n" "#define HAVE_NCURSES_PANEL_H 1" >>confdefs.h
+
+fi
+ac_fn_c_check_header_compile "$LINENO" "curses.h" "ac_cv_header_curses_h" "$ac_includes_default"
+if test "x$ac_cv_header_curses_h" = xyes
+then :
+ printf "%s\n" "#define HAVE_CURSES_H 1" >>confdefs.h
+
+fi
+ac_fn_c_check_header_compile "$LINENO" "ncurses.h" "ac_cv_header_ncurses_h" "$ac_includes_default"
+if test "x$ac_cv_header_ncurses_h" = xyes
+then :
+ printf "%s\n" "#define HAVE_NCURSES_H 1" >>confdefs.h
+
+fi
+ac_fn_c_check_header_compile "$LINENO" "panel.h" "ac_cv_header_panel_h" "$ac_includes_default"
+if test "x$ac_cv_header_panel_h" = xyes
+then :
+ printf "%s\n" "#define HAVE_PANEL_H 1" >>confdefs.h
+
+fi
+
+
+ # Check that we're able to link with crucial curses/panel functions. This
+ # also serves as a fallback in case pkg-config failed.
+ as_fn_append LIBS " $CURSES_LIBS $PANEL_LIBS"
+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for library containing initscr" >&5
+printf %s "checking for library containing initscr... " >&6; }
+if test ${ac_cv_search_initscr+y}
then :
printf %s "(cached) " >&6
else $as_nop
- ac_check_lib_save_LIBS=$LIBS
-LIBS="-lpanel $LIBS"
+ ac_func_search_save_LIBS=$LIBS
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
/* Override any GCC internal prototype to avoid an error.
Use char because int might match the return type of a GCC
builtin and then its argument prototype would still apply. */
-char update_panels ();
+char initscr ();
int
main (void)
{
-return update_panels ();
+return initscr ();
;
return 0;
}
_ACEOF
-if ac_fn_c_try_link "$LINENO"
+for ac_lib in '' ncursesw ncurses
+do
+ if test -z "$ac_lib"; then
+ ac_res="none required"
+ else
+ ac_res=-l$ac_lib
+ LIBS="-l$ac_lib $ac_func_search_save_LIBS"
+ fi
+ if ac_fn_c_try_link "$LINENO"
then :
- ac_cv_lib_panel_update_panels=yes
-else $as_nop
- ac_cv_lib_panel_update_panels=no
+ ac_cv_search_initscr=$ac_res
fi
rm -f core conftest.err conftest.$ac_objext conftest.beam \
- conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
+ conftest$ac_exeext
+ if test ${ac_cv_search_initscr+y}
+then :
+ break
fi
-{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_panel_update_panels" >&5
-printf "%s\n" "$ac_cv_lib_panel_update_panels" >&6; }
-if test "x$ac_cv_lib_panel_update_panels" = xyes
+done
+if test ${ac_cv_search_initscr+y}
then :
- have_panel=panel
- PANEL_CFLAGS=${PANEL_CFLAGS-""}
- PANEL_LIBS=${PANEL_LIBS-"-lpanel"}
-
+else $as_nop
+ ac_cv_search_initscr=no
+fi
+rm conftest.$ac_ext
+LIBS=$ac_func_search_save_LIBS
+fi
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_initscr" >&5
+printf "%s\n" "$ac_cv_search_initscr" >&6; }
+ac_res=$ac_cv_search_initscr
+if test "$ac_res" != no
+then :
+ test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
+ if test "x$have_curses" = xno
+then :
+ have_curses=yes
+ CURSES_LIBS=${CURSES_LIBS-"$ac_cv_search_initscr"}
+fi
+else $as_nop
+ have_curses=no
fi
-
-CFLAGS=$save_CFLAGS
-CPPFLAGS=$save_CPPFLAGS
-LDFLAGS=$save_LDFLAGS
-LIBS=$save_LIBS
-
-
-
-elif test $pkg_failed = untried; then
- { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
-printf "%s\n" "no" >&6; }
-
- save_CFLAGS=$CFLAGS
-save_CPPFLAGS=$CPPFLAGS
-save_LDFLAGS=$LDFLAGS
-save_LIBS=$LIBS
-
-
- { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for update_panels in -lpanel" >&5
-printf %s "checking for update_panels in -lpanel... " >&6; }
-if test ${ac_cv_lib_panel_update_panels+y}
+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for library containing update_panels" >&5
+printf %s "checking for library containing update_panels... " >&6; }
+if test ${ac_cv_search_update_panels+y}
then :
printf %s "(cached) " >&6
else $as_nop
- ac_check_lib_save_LIBS=$LIBS
-LIBS="-lpanel $LIBS"
+ ac_func_search_save_LIBS=$LIBS
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
@@ -26881,76 +26545,82 @@ return update_panels ();
return 0;
}
_ACEOF
-if ac_fn_c_try_link "$LINENO"
+for ac_lib in '' panelw panel
+do
+ if test -z "$ac_lib"; then
+ ac_res="none required"
+ else
+ ac_res=-l$ac_lib
+ LIBS="-l$ac_lib $ac_func_search_save_LIBS"
+ fi
+ if ac_fn_c_try_link "$LINENO"
then :
- ac_cv_lib_panel_update_panels=yes
-else $as_nop
- ac_cv_lib_panel_update_panels=no
+ ac_cv_search_update_panels=$ac_res
fi
rm -f core conftest.err conftest.$ac_objext conftest.beam \
- conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
+ conftest$ac_exeext
+ if test ${ac_cv_search_update_panels+y}
+then :
+ break
fi
-{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_panel_update_panels" >&5
-printf "%s\n" "$ac_cv_lib_panel_update_panels" >&6; }
-if test "x$ac_cv_lib_panel_update_panels" = xyes
+done
+if test ${ac_cv_search_update_panels+y}
then :
- have_panel=panel
- PANEL_CFLAGS=${PANEL_CFLAGS-""}
- PANEL_LIBS=${PANEL_LIBS-"-lpanel"}
-
+else $as_nop
+ ac_cv_search_update_panels=no
fi
-
-
-CFLAGS=$save_CFLAGS
-CPPFLAGS=$save_CPPFLAGS
-LDFLAGS=$save_LDFLAGS
-LIBS=$save_LIBS
-
-
-
-else
- PANEL_CFLAGS=$pkg_cv_PANEL_CFLAGS
- PANEL_LIBS=$pkg_cv_PANEL_LIBS
- { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-printf "%s\n" "yes" >&6; }
-
- have_panel=panel
-
+rm conftest.$ac_ext
+LIBS=$ac_func_search_save_LIBS
fi
-
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_update_panels" >&5
+printf "%s\n" "$ac_cv_search_update_panels" >&6; }
+ac_res=$ac_cv_search_update_panels
+if test "$ac_res" != no
+then :
+ test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
+ if test "x$have_panel" = xno
+then :
+ have_panel=yes
+ PANEL_LIBS=${PANEL_LIBS-"$ac_cv_search_update_panels"}
+fi
+else $as_nop
+ have_panel=no
fi
-fi
-PANEL_CFLAGS=$(echo $PANEL_CFLAGS | sed 's/-D_XOPEN_SOURCE=600//g')
-{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking panel flags" >&5
-printf %s "checking panel flags... " >&6; }
-if test "x$have_panel" = xno
+
+if test "have_curses" != "no"
then :
- { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
-printf "%s\n" "no" >&6; }
+CURSES_CFLAGS=$(echo $CURSES_CFLAGS | sed 's/-D_XOPEN_SOURCE=600//g')
-else $as_nop
+if test "x$ac_sys_system" = xDarwin
+then :
- { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $have_panel (CFLAGS: $PANEL_CFLAGS, LIBS: $PANEL_LIBS)" >&5
-printf "%s\n" "$have_panel (CFLAGS: $PANEL_CFLAGS, LIBS: $PANEL_LIBS)" >&6; }
-fi
+ as_fn_append CURSES_CFLAGS " -D_XOPEN_SOURCE_EXTENDED=1"
-# first curses header check
-ac_save_cppflags="$CPPFLAGS"
-if test "$cross_compiling" = no; then
- CPPFLAGS="$CPPFLAGS -I/usr/include/ncursesw"
fi
+PANEL_CFLAGS=$(echo $PANEL_CFLAGS | sed 's/-D_XOPEN_SOURCE=600//g')
+
# On Solaris, term.h requires curses.h
ac_fn_c_check_header_compile "$LINENO" "term.h" "ac_cv_header_term_h" "
-#ifdef HAVE_CURSES_H
-#include <curses.h>
+#define NCURSES_OPAQUE 0
+#if defined(HAVE_NCURSESW_NCURSES_H)
+# include <ncursesw/ncurses.h>
+#elif defined(HAVE_NCURSESW_CURSES_H)
+# include <ncursesw/curses.h>
+#elif defined(HAVE_NCURSES_NCURSES_H)
+# include <ncurses/ncurses.h>
+#elif defined(HAVE_NCURSES_CURSES_H)
+# include <ncurses/curses.h>
+#elif defined(HAVE_NCURSES_H)
+# include <ncurses.h>
+#elif defined(HAVE_CURSES_H)
+# include <curses.h>
#endif
"
@@ -26970,7 +26640,22 @@ then :
else $as_nop
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
-#include <curses.h>
+
+#define NCURSES_OPAQUE 0
+#if defined(HAVE_NCURSESW_NCURSES_H)
+# include <ncursesw/ncurses.h>
+#elif defined(HAVE_NCURSESW_CURSES_H)
+# include <ncursesw/curses.h>
+#elif defined(HAVE_NCURSES_NCURSES_H)
+# include <ncurses/ncurses.h>
+#elif defined(HAVE_NCURSES_CURSES_H)
+# include <ncurses/curses.h>
+#elif defined(HAVE_NCURSES_H)
+# include <ncurses.h>
+#elif defined(HAVE_CURSES_H)
+# include <curses.h>
+#endif
+
int
main (void)
{
@@ -27000,10 +26685,6 @@ printf "%s\n" "#define MVWDELCH_IS_EXPRESSION 1" >>confdefs.h
fi
-# Issue #25720: ncurses has introduced the NCURSES_OPAQUE symbol making opaque
-# structs since version 5.7. If the macro is defined as zero before including
-# [n]curses.h, ncurses will expose fields of the structs regardless of the
-# configuration.
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether WINDOW has _flags" >&5
printf %s "checking whether WINDOW has _flags... " >&6; }
if test ${ac_cv_window_has_flags+y}
@@ -27013,8 +26694,20 @@ else $as_nop
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
- #define NCURSES_OPAQUE 0
- #include <curses.h>
+#define NCURSES_OPAQUE 0
+#if defined(HAVE_NCURSESW_NCURSES_H)
+# include <ncursesw/ncurses.h>
+#elif defined(HAVE_NCURSESW_CURSES_H)
+# include <ncursesw/curses.h>
+#elif defined(HAVE_NCURSES_NCURSES_H)
+# include <ncurses/ncurses.h>
+#elif defined(HAVE_NCURSES_CURSES_H)
+# include <ncurses/curses.h>
+#elif defined(HAVE_NCURSES_H)
+# include <ncurses.h>
+#elif defined(HAVE_CURSES_H)
+# include <curses.h>
+#endif
int
main (void)
@@ -27059,8 +26752,20 @@ else $as_nop
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
- #define NCURSES_OPAQUE 0
- #include <curses.h>
+#define NCURSES_OPAQUE 0
+#if defined(HAVE_NCURSESW_NCURSES_H)
+# include <ncursesw/ncurses.h>
+#elif defined(HAVE_NCURSESW_CURSES_H)
+# include <ncursesw/curses.h>
+#elif defined(HAVE_NCURSES_NCURSES_H)
+# include <ncurses/ncurses.h>
+#elif defined(HAVE_NCURSES_CURSES_H)
+# include <ncurses/curses.h>
+#elif defined(HAVE_NCURSES_H)
+# include <ncurses.h>
+#elif defined(HAVE_CURSES_H)
+# include <curses.h>
+#endif
int
main (void)
@@ -27105,8 +26810,20 @@ else $as_nop
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
- #define NCURSES_OPAQUE 0
- #include <curses.h>
+#define NCURSES_OPAQUE 0
+#if defined(HAVE_NCURSESW_NCURSES_H)
+# include <ncursesw/ncurses.h>
+#elif defined(HAVE_NCURSESW_CURSES_H)
+# include <ncursesw/curses.h>
+#elif defined(HAVE_NCURSES_NCURSES_H)
+# include <ncurses/ncurses.h>
+#elif defined(HAVE_NCURSES_CURSES_H)
+# include <ncurses/curses.h>
+#elif defined(HAVE_NCURSES_H)
+# include <ncurses.h>
+#elif defined(HAVE_CURSES_H)
+# include <curses.h>
+#endif
int
main (void)
@@ -27151,8 +26868,20 @@ else $as_nop
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
- #define NCURSES_OPAQUE 0
- #include <curses.h>
+#define NCURSES_OPAQUE 0
+#if defined(HAVE_NCURSESW_NCURSES_H)
+# include <ncursesw/ncurses.h>
+#elif defined(HAVE_NCURSESW_CURSES_H)
+# include <ncursesw/curses.h>
+#elif defined(HAVE_NCURSES_NCURSES_H)
+# include <ncurses/ncurses.h>
+#elif defined(HAVE_NCURSES_CURSES_H)
+# include <ncurses/curses.h>
+#elif defined(HAVE_NCURSES_H)
+# include <ncurses.h>
+#elif defined(HAVE_CURSES_H)
+# include <curses.h>
+#endif
int
main (void)
@@ -27197,8 +26926,20 @@ else $as_nop
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
- #define NCURSES_OPAQUE 0
- #include <curses.h>
+#define NCURSES_OPAQUE 0
+#if defined(HAVE_NCURSESW_NCURSES_H)
+# include <ncursesw/ncurses.h>
+#elif defined(HAVE_NCURSESW_CURSES_H)
+# include <ncursesw/curses.h>
+#elif defined(HAVE_NCURSES_NCURSES_H)
+# include <ncurses/ncurses.h>
+#elif defined(HAVE_NCURSES_CURSES_H)
+# include <ncurses/curses.h>
+#elif defined(HAVE_NCURSES_H)
+# include <ncurses.h>
+#elif defined(HAVE_CURSES_H)
+# include <curses.h>
+#endif
int
main (void)
@@ -27243,8 +26984,20 @@ else $as_nop
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
- #define NCURSES_OPAQUE 0
- #include <curses.h>
+#define NCURSES_OPAQUE 0
+#if defined(HAVE_NCURSESW_NCURSES_H)
+# include <ncursesw/ncurses.h>
+#elif defined(HAVE_NCURSESW_CURSES_H)
+# include <ncursesw/curses.h>
+#elif defined(HAVE_NCURSES_NCURSES_H)
+# include <ncurses/ncurses.h>
+#elif defined(HAVE_NCURSES_CURSES_H)
+# include <ncurses/curses.h>
+#elif defined(HAVE_NCURSES_H)
+# include <ncurses.h>
+#elif defined(HAVE_CURSES_H)
+# include <curses.h>
+#endif
int
main (void)
@@ -27289,8 +27042,20 @@ else $as_nop
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
- #define NCURSES_OPAQUE 0
- #include <curses.h>
+#define NCURSES_OPAQUE 0
+#if defined(HAVE_NCURSESW_NCURSES_H)
+# include <ncursesw/ncurses.h>
+#elif defined(HAVE_NCURSESW_CURSES_H)
+# include <ncursesw/curses.h>
+#elif defined(HAVE_NCURSES_NCURSES_H)
+# include <ncurses/ncurses.h>
+#elif defined(HAVE_NCURSES_CURSES_H)
+# include <ncurses/curses.h>
+#elif defined(HAVE_NCURSES_H)
+# include <ncurses.h>
+#elif defined(HAVE_CURSES_H)
+# include <curses.h>
+#endif
int
main (void)
@@ -27335,8 +27100,20 @@ else $as_nop
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
- #define NCURSES_OPAQUE 0
- #include <curses.h>
+#define NCURSES_OPAQUE 0
+#if defined(HAVE_NCURSESW_NCURSES_H)
+# include <ncursesw/ncurses.h>
+#elif defined(HAVE_NCURSESW_CURSES_H)
+# include <ncursesw/curses.h>
+#elif defined(HAVE_NCURSES_NCURSES_H)
+# include <ncurses/ncurses.h>
+#elif defined(HAVE_NCURSES_CURSES_H)
+# include <ncurses/curses.h>
+#elif defined(HAVE_NCURSES_H)
+# include <ncurses.h>
+#elif defined(HAVE_CURSES_H)
+# include <curses.h>
+#endif
int
main (void)
@@ -27381,8 +27158,20 @@ else $as_nop
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
- #define NCURSES_OPAQUE 0
- #include <curses.h>
+#define NCURSES_OPAQUE 0
+#if defined(HAVE_NCURSESW_NCURSES_H)
+# include <ncursesw/ncurses.h>
+#elif defined(HAVE_NCURSESW_CURSES_H)
+# include <ncursesw/curses.h>
+#elif defined(HAVE_NCURSES_NCURSES_H)
+# include <ncurses/ncurses.h>
+#elif defined(HAVE_NCURSES_CURSES_H)
+# include <ncurses/curses.h>
+#elif defined(HAVE_NCURSES_H)
+# include <ncurses.h>
+#elif defined(HAVE_CURSES_H)
+# include <curses.h>
+#endif
int
main (void)
@@ -27427,8 +27216,20 @@ else $as_nop
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
- #define NCURSES_OPAQUE 0
- #include <curses.h>
+#define NCURSES_OPAQUE 0
+#if defined(HAVE_NCURSESW_NCURSES_H)
+# include <ncursesw/ncurses.h>
+#elif defined(HAVE_NCURSESW_CURSES_H)
+# include <ncursesw/curses.h>
+#elif defined(HAVE_NCURSES_NCURSES_H)
+# include <ncurses/ncurses.h>
+#elif defined(HAVE_NCURSES_CURSES_H)
+# include <ncurses/curses.h>
+#elif defined(HAVE_NCURSES_H)
+# include <ncurses.h>
+#elif defined(HAVE_CURSES_H)
+# include <curses.h>
+#endif
int
main (void)
@@ -27473,8 +27274,20 @@ else $as_nop
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
- #define NCURSES_OPAQUE 0
- #include <curses.h>
+#define NCURSES_OPAQUE 0
+#if defined(HAVE_NCURSESW_NCURSES_H)
+# include <ncursesw/ncurses.h>
+#elif defined(HAVE_NCURSESW_CURSES_H)
+# include <ncursesw/curses.h>
+#elif defined(HAVE_NCURSES_NCURSES_H)
+# include <ncurses/ncurses.h>
+#elif defined(HAVE_NCURSES_CURSES_H)
+# include <ncurses/curses.h>
+#elif defined(HAVE_NCURSES_H)
+# include <ncurses.h>
+#elif defined(HAVE_CURSES_H)
+# include <curses.h>
+#endif
int
main (void)
@@ -27519,8 +27332,20 @@ else $as_nop
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
- #define NCURSES_OPAQUE 0
- #include <curses.h>
+#define NCURSES_OPAQUE 0
+#if defined(HAVE_NCURSESW_NCURSES_H)
+# include <ncursesw/ncurses.h>
+#elif defined(HAVE_NCURSESW_CURSES_H)
+# include <ncursesw/curses.h>
+#elif defined(HAVE_NCURSES_NCURSES_H)
+# include <ncurses/ncurses.h>
+#elif defined(HAVE_NCURSES_CURSES_H)
+# include <ncurses/curses.h>
+#elif defined(HAVE_NCURSES_H)
+# include <ncurses.h>
+#elif defined(HAVE_CURSES_H)
+# include <curses.h>
+#endif
int
main (void)
@@ -27556,6 +27381,13 @@ fi
CPPFLAGS=$ac_save_cppflags
+fi
+CFLAGS=$save_CFLAGS
+CPPFLAGS=$save_CPPFLAGS
+LDFLAGS=$save_LDFLAGS
+LIBS=$save_LIBS
+
+
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for device files" >&5
printf "%s\n" "$as_me: checking for device files" >&6;}
@@ -30625,7 +30457,7 @@ then :
if true
then :
- if test "$have_curses" != "no"
+ if test "$have_curses" = "yes"
then :
py_cv_module__curses=yes
else $as_nop
@@ -30664,7 +30496,7 @@ then :
if true
then :
- if test "$have_panel" != "no"
+ if test "$have_curses" = "yes" && test "$have_panel" = "yes"
then :
py_cv_module__curses_panel=yes
else $as_nop
diff --git a/configure.ac b/configure.ac
index e4f8f4112283a8..460dd8916bc5aa 100644
--- a/configure.ac
+++ b/configure.ac
@@ -6663,55 +6663,88 @@ then
[Define if year with century should be normalized for strftime.])
fi
-dnl check for ncurses/ncursesw and panel/panelw
+dnl check for ncursesw/ncurses and panelw/panel
dnl NOTE: old curses is not detected.
-dnl have_curses=[no, ncursesw, ncurses]
-dnl have_panel=[no, panelw, panel]
+dnl have_curses=[no, yes]
+dnl have_panel=[no, yes]
have_curses=no
have_panel=no
-AH_TEMPLATE([HAVE_NCURSESW], [Define to 1 if you have the `ncursesw' library.])
-AC_CHECK_HEADERS([curses.h ncurses.h])
+dnl PY_CHECK_CURSES(LIBCURSES, LIBPANEL)
+dnl Sets 'have_curses' and 'have_panel'.
+dnl For the PKG_CHECK_MODULES() calls, we can safely reuse the first variable
+dnl here, since we're only calling the macro a second time if the first call
+dnl fails.
+AC_DEFUN([PY_CHECK_CURSES], [dnl
+AS_VAR_PUSHDEF([curses_var], [m4_toupper([$1])])
+AS_VAR_PUSHDEF([panel_var], [m4_toupper([$2])])
+PKG_CHECK_MODULES([CURSES], [$1],
+ [AC_DEFINE([HAVE_]curses_var, [1], [Define if you have the '$1' library])
+ AS_VAR_SET([have_curses], [yes])
+ PKG_CHECK_MODULES([PANEL], [$2],
+ [AC_DEFINE([HAVE_]panel_var, [1], [Define if you have the '$2' library])
+ AS_VAR_SET([have_panel], [yes])],
+ [AS_VAR_SET([have_panel], [no])])],
+ [AS_VAR_SET([have_curses], [no])])
+AS_VAR_POPDEF([curses_var])
+AS_VAR_POPDEF([panel_var])])
+
+# Check for ncursesw/panelw first. If that fails, try ncurses/panel.
+PY_CHECK_CURSES([ncursesw], [panelw])
+AS_VAR_IF([have_curses], [no],
+ [PY_CHECK_CURSES([ncurses], [panel])])
-AS_VAR_IF([ac_cv_header_ncurses_h], [yes], [
- if test "$ac_sys_system" != "Darwin"; then
- dnl On macOS, there is no separate /usr/lib/libncursesw nor libpanelw.
- PKG_CHECK_MODULES([CURSES], [ncursesw], [
- AC_DEFINE([HAVE_NCURSESW], [1])
- have_curses=ncursesw
- ], [
- WITH_SAVE_ENV([
- AC_CHECK_LIB([ncursesw], [initscr], [
- AC_DEFINE([HAVE_NCURSESW], [1])
- have_curses=ncursesw
- CURSES_CFLAGS=${CURSES_CFLAGS-""}
- CURSES_LIBS=${CURSES_LIBS-"-lncursesw"}
- ])
- ])
- ])
- fi
-
- AS_VAR_IF([have_curses], [no], [
- PKG_CHECK_MODULES([CURSES], [ncurses], [
- have_curses=ncurses
- ], [
- WITH_SAVE_ENV([
- AC_CHECK_LIB([ncurses], [initscr], [
- have_curses=ncurses
- CURSES_CFLAGS=${CURSES_CFLAGS-""}
- CURSES_LIBS=${CURSES_LIBS-"-lncurses"}
- ])
- ])
- ])
- ])
+WITH_SAVE_ENV([
+ # Make sure we've got the header defines.
+ AS_VAR_APPEND([CPPFLAGS], [" $CURSES_CFLAGS $PANEL_CFLAGS"])
+ AC_CHECK_HEADERS(m4_normalize([
+ ncursesw/curses.h ncursesw/ncurses.h ncursesw/panel.h
+ ncurses/curses.h ncurses/ncurses.h ncurses/panel.h
+ curses.h ncurses.h panel.h
+ ]))
-])dnl ac_cv_header_ncurses_h = yes
+ # Check that we're able to link with crucial curses/panel functions. This
+ # also serves as a fallback in case pkg-config failed.
+ AS_VAR_APPEND([LIBS], [" $CURSES_LIBS $PANEL_LIBS"])
+ AC_SEARCH_LIBS([initscr], [ncursesw ncurses],
+ [AS_VAR_IF([have_curses], [no],
+ [AS_VAR_SET([have_curses], [yes])
+ CURSES_LIBS=${CURSES_LIBS-"$ac_cv_search_initscr"}])],
+ [AS_VAR_SET([have_curses], [no])])
+ AC_SEARCH_LIBS([update_panels], [panelw panel],
+ [AS_VAR_IF([have_panel], [no],
+ [AS_VAR_SET([have_panel], [yes])
+ PANEL_LIBS=${PANEL_LIBS-"$ac_cv_search_update_panels"}])],
+ [AS_VAR_SET([have_panel], [no])])
+
+dnl Issue #25720: ncurses has introduced the NCURSES_OPAQUE symbol making opaque
+dnl structs since version 5.7. If the macro is defined as zero before including
+dnl [n]curses.h, ncurses will expose fields of the structs regardless of the
+dnl configuration.
+AC_DEFUN([_CURSES_INCLUDES],dnl
+[
+#define NCURSES_OPAQUE 0
+#if defined(HAVE_NCURSESW_NCURSES_H)
+# include <ncursesw/ncurses.h>
+#elif defined(HAVE_NCURSESW_CURSES_H)
+# include <ncursesw/curses.h>
+#elif defined(HAVE_NCURSES_NCURSES_H)
+# include <ncurses/ncurses.h>
+#elif defined(HAVE_NCURSES_CURSES_H)
+# include <ncurses/curses.h>
+#elif defined(HAVE_NCURSES_H)
+# include <ncurses.h>
+#elif defined(HAVE_CURSES_H)
+# include <curses.h>
+#endif
+])
+AS_IF([test "have_curses" != "no"], [
dnl remove _XOPEN_SOURCE macro from curses cflags. pyconfig.h sets
dnl the macro to 700.
CURSES_CFLAGS=$(echo $CURSES_CFLAGS | sed 's/-D_XOPEN_SOURCE=600//g')
-if test "$have_curses" != no -a "$ac_sys_system" = "Darwin"; then
+AS_VAR_IF([ac_sys_system], [Darwin], [
dnl On macOS, there is no separate /usr/lib/libncursesw nor libpanelw.
dnl System-supplied ncurses combines libncurses/libpanel and supports wide
dnl characters, so we can use it like ncursesw.
@@ -6721,82 +6754,17 @@ if test "$have_curses" != no -a "$ac_sys_system" = "Darwin"; then
dnl _XOPEN_SOURCE_EXTENDED here for ncurses wide char support.
AS_VAR_APPEND([CURSES_CFLAGS], [" -D_XOPEN_SOURCE_EXTENDED=1"])
- AC_DEFINE([HAVE_NCURSESW], [1])
-fi
-
-dnl TODO: detect "curses" and special cases tinfo, terminfo, or termcap
-
-AC_MSG_CHECKING([curses module flags])
-AS_VAR_IF([have_curses], [no], [
- AC_MSG_RESULT([no])
-], [
- AC_MSG_RESULT([$have_curses (CFLAGS: $CURSES_CFLAGS, LIBS: $CURSES_LIBS)])
])
-dnl check for ncurses' panel/panelw library
-AC_CHECK_HEADERS([panel.h])
-
-AS_VAR_IF([ac_cv_header_panel_h], [yes], [
-
- if test "$ac_sys_system" != "Darwin"; then
- dnl On macOS, there is no separate /usr/lib/libncursesw nor libpanelw.
- AS_VAR_IF([have_curses], [ncursesw], [
- PKG_CHECK_MODULES([PANEL], [panelw], [
- have_panel=panelw
- ], [
- WITH_SAVE_ENV([
- AC_CHECK_LIB([panelw], [update_panels], [
- have_panel=panelw
- PANEL_CFLAGS=${PANEL_CFLAGS-""}
- PANEL_LIBS=${PANEL_LIBS-"-lpanelw"}
- ])
- ])
- ])
- ])
- fi
-
- AS_VAR_IF([have_curses], [ncurses], [
- PKG_CHECK_MODULES([PANEL], [panel], [
- have_panel=panel
- ], [
- WITH_SAVE_ENV([
- AC_CHECK_LIB([panel], [update_panels], [
- have_panel=panel
- PANEL_CFLAGS=${PANEL_CFLAGS-""}
- PANEL_LIBS=${PANEL_LIBS-"-lpanel"}
- ])
- ])
- ])
- ])
-
-])dnl ac_cv_header_panel_h = yes
-
dnl pyconfig.h defines _XOPEN_SOURCE=700
PANEL_CFLAGS=$(echo $PANEL_CFLAGS | sed 's/-D_XOPEN_SOURCE=600//g')
-AC_MSG_CHECKING([panel flags])
-AS_VAR_IF([have_panel], [no], [
- AC_MSG_RESULT([no])
-], [
- AC_MSG_RESULT([$have_panel (CFLAGS: $PANEL_CFLAGS, LIBS: $PANEL_LIBS)])
-])
-
-# first curses header check
-ac_save_cppflags="$CPPFLAGS"
-if test "$cross_compiling" = no; then
- CPPFLAGS="$CPPFLAGS -I/usr/include/ncursesw"
-fi
-
# On Solaris, term.h requires curses.h
-AC_CHECK_HEADERS([term.h], [], [], [
-#ifdef HAVE_CURSES_H
-#include <curses.h>
-#endif
-])
+AC_CHECK_HEADERS([term.h], [], [], _CURSES_INCLUDES)
# On HP/UX 11.0, mvwdelch is a block with a return statement
AC_CACHE_CHECK([whether mvwdelch is an expression], [ac_cv_mvwdelch_is_expression],
-AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[@%:@include <curses.h>]], [[
+AC_COMPILE_IFELSE([AC_LANG_PROGRAM(_CURSES_INCLUDES, [[
int rtn;
rtn = mvwdelch(0,0,0);
]])],
@@ -6809,15 +6777,8 @@ then
[Define if mvwdelch in curses.h is an expression.])
fi
-# Issue #25720: ncurses has introduced the NCURSES_OPAQUE symbol making opaque
-# structs since version 5.7. If the macro is defined as zero before including
-# [n]curses.h, ncurses will expose fields of the structs regardless of the
-# configuration.
AC_CACHE_CHECK([whether WINDOW has _flags], [ac_cv_window_has_flags],
-AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
- #define NCURSES_OPAQUE 0
- #include <curses.h>
-]], [[
+AC_COMPILE_IFELSE([AC_LANG_PROGRAM(_CURSES_INCLUDES, [[
WINDOW *w;
w->_flags = 0;
]])],
@@ -6839,11 +6800,7 @@ AC_DEFUN([PY_CHECK_CURSES_FUNC],
[for curses function $1],
[py_var],
[AC_COMPILE_IFELSE(
- [AC_LANG_PROGRAM(
- [
- #define NCURSES_OPAQUE 0
- #include <curses.h>
- ], [
+ [AC_LANG_PROGRAM(_CURSES_INCLUDES, [
#ifndef $1
void *x=$1
#endif
@@ -6871,6 +6828,8 @@ PY_CHECK_CURSES_FUNC([has_key])
PY_CHECK_CURSES_FUNC([typeahead])
PY_CHECK_CURSES_FUNC([use_env])
CPPFLAGS=$ac_save_cppflags
+])dnl have_curses != no
+])dnl save env
AC_MSG_NOTICE([checking for device files])
@@ -7788,11 +7747,11 @@ PY_STDLIB_MOD([_ctypes],
[], [test "$have_libffi" = yes],
[$NO_STRICT_OVERFLOW_CFLAGS $LIBFFI_CFLAGS], [$LIBFFI_LIBS])
PY_STDLIB_MOD([_curses],
- [], [test "$have_curses" != "no"],
+ [], [test "$have_curses" = "yes"],
[$CURSES_CFLAGS], [$CURSES_LIBS]
)
PY_STDLIB_MOD([_curses_panel],
- [], [test "$have_panel" != "no"],
+ [], [test "$have_curses" = "yes" && test "$have_panel" = "yes"],
[$PANEL_CFLAGS $CURSES_CFLAGS], [$PANEL_LIBS $CURSES_LIBS]
)
PY_STDLIB_MOD([_decimal],
diff --git a/pyconfig.h.in b/pyconfig.h.in
index a90f9363f0ccab..10980c92176a7e 100644
--- a/pyconfig.h.in
+++ b/pyconfig.h.in
@@ -829,12 +829,33 @@
/* Define to 1 if you have the `nanosleep' function. */
#undef HAVE_NANOSLEEP
-/* Define to 1 if you have the `ncursesw' library. */
+/* Define if you have the 'ncurses' library */
+#undef HAVE_NCURSES
+
+/* Define if you have the 'ncursesw' library */
#undef HAVE_NCURSESW
+/* Define to 1 if you have the <ncursesw/curses.h> header file. */
+#undef HAVE_NCURSESW_CURSES_H
+
+/* Define to 1 if you have the <ncursesw/ncurses.h> header file. */
+#undef HAVE_NCURSESW_NCURSES_H
+
+/* Define to 1 if you have the <ncursesw/panel.h> header file. */
+#undef HAVE_NCURSESW_PANEL_H
+
+/* Define to 1 if you have the <ncurses/curses.h> header file. */
+#undef HAVE_NCURSES_CURSES_H
+
/* Define to 1 if you have the <ncurses.h> header file. */
#undef HAVE_NCURSES_H
+/* Define to 1 if you have the <ncurses/ncurses.h> header file. */
+#undef HAVE_NCURSES_NCURSES_H
+
+/* Define to 1 if you have the <ncurses/panel.h> header file. */
+#undef HAVE_NCURSES_PANEL_H
+
/* Define to 1 if you have the <ndbm.h> header file. */
#undef HAVE_NDBM_H
@@ -878,6 +899,12 @@
/* Define to 1 if you have the `openpty' function. */
#undef HAVE_OPENPTY
+/* Define if you have the 'panel' library */
+#undef HAVE_PANEL
+
+/* Define if you have the 'panelw' library */
+#undef HAVE_PANELW
+
/* Define to 1 if you have the <panel.h> header file. */
#undef HAVE_PANEL_H
1
0
[3.13] gh-87744: fix waitpid race while calling send_signal in asyncio (GH-121126) (#121194)
by kumaraditya303 July 1, 2024
by kumaraditya303 July 1, 2024
July 1, 2024
https://github.com/python/cpython/commit/d481d4b7676f2e5d33465ca691346f69af…
commit: d481d4b7676f2e5d33465ca691346f69af655b24
branch: 3.13
author: Miss Islington (bot) <31488909+miss-islington(a)users.noreply.github.com>
committer: kumaraditya303 <kumaraditya(a)python.org>
date: 2024-07-01T05:11:47Z
summary:
[3.13] gh-87744: fix waitpid race while calling send_signal in asyncio (GH-121126) (#121194)
gh-87744: fix waitpid race while calling send_signal in asyncio (GH-121126)
asyncio earlier relied on subprocess module to send signals to the process, this has some drawbacks one being that subprocess module unnecessarily calls waitpid on child processes and hence it races with asyncio implementation which internally uses child watchers. To mitigate this, now asyncio sends signals directly to the process without going through the subprocess on non windows systems. On Windows it fallbacks to subprocess module handling but on windows there are no child watchers so this issue doesn't exists altogether.
(cherry picked from commit bd473aa598c5161521a7018896dc124728214a6c)
Co-authored-by: Kumar Aditya <kumaraditya(a)python.org>
files:
A Misc/NEWS.d/next/Library/2024-06-29-05-08-59.gh-issue-87744.rpF6Jw.rst
M Lib/asyncio/base_subprocess.py
M Lib/test/test_asyncio/test_subprocess.py
diff --git a/Lib/asyncio/base_subprocess.py b/Lib/asyncio/base_subprocess.py
index 6dbde2b696ad1f..9c2ba679ce2bf1 100644
--- a/Lib/asyncio/base_subprocess.py
+++ b/Lib/asyncio/base_subprocess.py
@@ -1,6 +1,9 @@
import collections
import subprocess
import warnings
+import os
+import signal
+import sys
from . import protocols
from . import transports
@@ -142,17 +145,31 @@ def _check_proc(self):
if self._proc is None:
raise ProcessLookupError()
- def send_signal(self, signal):
- self._check_proc()
- self._proc.send_signal(signal)
+ if sys.platform == 'win32':
+ def send_signal(self, signal):
+ self._check_proc()
+ self._proc.send_signal(signal)
+
+ def terminate(self):
+ self._check_proc()
+ self._proc.terminate()
+
+ def kill(self):
+ self._check_proc()
+ self._proc.kill()
+ else:
+ def send_signal(self, signal):
+ self._check_proc()
+ try:
+ os.kill(self._proc.pid, signal)
+ except ProcessLookupError:
+ pass
- def terminate(self):
- self._check_proc()
- self._proc.terminate()
+ def terminate(self):
+ self.send_signal(signal.SIGTERM)
- def kill(self):
- self._check_proc()
- self._proc.kill()
+ def kill(self):
+ self.send_signal(signal.SIGKILL)
async def _connect_pipes(self, waiter):
try:
diff --git a/Lib/test/test_asyncio/test_subprocess.py b/Lib/test/test_asyncio/test_subprocess.py
index cf1a1985338e40..c822d8045b0c0f 100644
--- a/Lib/test/test_asyncio/test_subprocess.py
+++ b/Lib/test/test_asyncio/test_subprocess.py
@@ -873,6 +873,21 @@ async def main():
self.loop.run_until_complete(main())
+ @unittest.skipIf(sys.platform != 'linux', "Linux only")
+ def test_subprocess_send_signal_race(self):
+ # See https://github.com/python/cpython/issues/87744
+ async def main():
+ for _ in range(10):
+ proc = await asyncio.create_subprocess_exec('sleep', '0.1')
+ await asyncio.sleep(0.1)
+ try:
+ proc.send_signal(signal.SIGUSR1)
+ except ProcessLookupError:
+ pass
+ self.assertNotEqual(await proc.wait(), 255)
+
+ self.loop.run_until_complete(main())
+
if sys.platform != 'win32':
# Unix
diff --git a/Misc/NEWS.d/next/Library/2024-06-29-05-08-59.gh-issue-87744.rpF6Jw.rst b/Misc/NEWS.d/next/Library/2024-06-29-05-08-59.gh-issue-87744.rpF6Jw.rst
new file mode 100644
index 00000000000000..c0b4f349fb6dac
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2024-06-29-05-08-59.gh-issue-87744.rpF6Jw.rst
@@ -0,0 +1 @@
+Fix waitpid race while calling :meth:`~asyncio.subprocess.Process.send_signal` in asyncio. Patch by Kumar Aditya.
1
0
gh-87744: fix waitpid race while calling send_signal in asyncio (#121126)
by kumaraditya303 June 30, 2024
by kumaraditya303 June 30, 2024
June 30, 2024
https://github.com/python/cpython/commit/bd473aa598c5161521a7018896dc124728…
commit: bd473aa598c5161521a7018896dc124728214a6c
branch: main
author: Kumar Aditya <kumaraditya(a)python.org>
committer: kumaraditya303 <kumaraditya(a)python.org>
date: 2024-07-01T10:17:36+05:30
summary:
gh-87744: fix waitpid race while calling send_signal in asyncio (#121126)
asyncio earlier relied on subprocess module to send signals to the process, this has some drawbacks one being that subprocess module unnecessarily calls waitpid on child processes and hence it races with asyncio implementation which internally uses child watchers. To mitigate this, now asyncio sends signals directly to the process without going through the subprocess on non windows systems. On Windows it fallbacks to subprocess module handling but on windows there are no child watchers so this issue doesn't exists altogether.
files:
A Misc/NEWS.d/next/Library/2024-06-29-05-08-59.gh-issue-87744.rpF6Jw.rst
M Lib/asyncio/base_subprocess.py
M Lib/test/test_asyncio/test_subprocess.py
diff --git a/Lib/asyncio/base_subprocess.py b/Lib/asyncio/base_subprocess.py
index 6dbde2b696ad1f..9c2ba679ce2bf1 100644
--- a/Lib/asyncio/base_subprocess.py
+++ b/Lib/asyncio/base_subprocess.py
@@ -1,6 +1,9 @@
import collections
import subprocess
import warnings
+import os
+import signal
+import sys
from . import protocols
from . import transports
@@ -142,17 +145,31 @@ def _check_proc(self):
if self._proc is None:
raise ProcessLookupError()
- def send_signal(self, signal):
- self._check_proc()
- self._proc.send_signal(signal)
+ if sys.platform == 'win32':
+ def send_signal(self, signal):
+ self._check_proc()
+ self._proc.send_signal(signal)
+
+ def terminate(self):
+ self._check_proc()
+ self._proc.terminate()
+
+ def kill(self):
+ self._check_proc()
+ self._proc.kill()
+ else:
+ def send_signal(self, signal):
+ self._check_proc()
+ try:
+ os.kill(self._proc.pid, signal)
+ except ProcessLookupError:
+ pass
- def terminate(self):
- self._check_proc()
- self._proc.terminate()
+ def terminate(self):
+ self.send_signal(signal.SIGTERM)
- def kill(self):
- self._check_proc()
- self._proc.kill()
+ def kill(self):
+ self.send_signal(signal.SIGKILL)
async def _connect_pipes(self, waiter):
try:
diff --git a/Lib/test/test_asyncio/test_subprocess.py b/Lib/test/test_asyncio/test_subprocess.py
index 23987c70ca7b63..54501300a29cf7 100644
--- a/Lib/test/test_asyncio/test_subprocess.py
+++ b/Lib/test/test_asyncio/test_subprocess.py
@@ -864,6 +864,21 @@ async def main():
self.loop.run_until_complete(main())
+ @unittest.skipIf(sys.platform != 'linux', "Linux only")
+ def test_subprocess_send_signal_race(self):
+ # See https://github.com/python/cpython/issues/87744
+ async def main():
+ for _ in range(10):
+ proc = await asyncio.create_subprocess_exec('sleep', '0.1')
+ await asyncio.sleep(0.1)
+ try:
+ proc.send_signal(signal.SIGUSR1)
+ except ProcessLookupError:
+ pass
+ self.assertNotEqual(await proc.wait(), 255)
+
+ self.loop.run_until_complete(main())
+
if sys.platform != 'win32':
# Unix
diff --git a/Misc/NEWS.d/next/Library/2024-06-29-05-08-59.gh-issue-87744.rpF6Jw.rst b/Misc/NEWS.d/next/Library/2024-06-29-05-08-59.gh-issue-87744.rpF6Jw.rst
new file mode 100644
index 00000000000000..c0b4f349fb6dac
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2024-06-29-05-08-59.gh-issue-87744.rpF6Jw.rst
@@ -0,0 +1 @@
+Fix waitpid race while calling :meth:`~asyncio.subprocess.Process.send_signal` in asyncio. Patch by Kumar Aditya.
1
0