From: Sunil Dora Date: Tue, 24 Mar 2026 16:45:27 +0000 (-0700) Subject: gdb/ser-unix: add POSIX cfsetispeed/cfsetospeed support for custom baud rates X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=7d53467645b0430e94a3cfd13fc3c16ef19efda5;p=thirdparty%2Fbinutils-gdb.git gdb/ser-unix: add POSIX cfsetispeed/cfsetospeed support for custom baud rates glibc 2.42 and later, and GNU Hurd, accept arbitrary baud rates directly via cfsetispeed and cfsetospeed. This behaviour is expected to be standardized in a future POSIX revision. Introduce a configure-time test (HAVE_CFSETSPEED_ARBITRARY) that detects this capability and add a new platform-agnostic helper set_custom_baudrate_posix. The main dispatcher now prefers the POSIX path when it is available, falling back to the existing Linux (BOTHER) or Darwin (IOSSIOSPEED) implementations otherwise. The HAVE_CUSTOM_BAUDRATE_SUPPORT guard is extended to also cover the new POSIX case. Suggested-by: Kevin Buettner Suggested-by: Maciej W. Rozycki Signed-off-by: Sunil Dora Reviewed-By: Eli Zaretskii Approved-by: Kevin Buettner --- diff --git a/gdb/NEWS b/gdb/NEWS index 4cf91053c95..89c2ac4384f 100644 --- a/gdb/NEWS +++ b/gdb/NEWS @@ -36,6 +36,12 @@ subsequent runs of the inferior will use the same arguments as the first run. +* GDB now supports arbitrary (non-standard) baud rates for serial + connections to remote targets on systems where the host libc accepts + them via cfsetispeed/cfsetospeed, such as glibc 2.42 and later and + GNU Hurd. On other systems, existing platform-specific mechanisms + are used. + * Support for stabs debug information has been removed. * Support for mdebug debug information has been removed. diff --git a/gdb/config.in b/gdb/config.in index 6ad5240397b..e357c22e411 100644 --- a/gdb/config.in +++ b/gdb/config.in @@ -110,6 +110,9 @@ the CoreFoundation framework. */ #undef HAVE_CFPREFERENCESCOPYAPPVALUE +/* Define if cfsetispeed/cfsetospeed accept arbitrary baud rates. */ +#undef HAVE_CFSETSPEED_ARBITRARY + /* Define to 1 if you have the `clearenv' function. */ #undef HAVE_CLEARENV diff --git a/gdb/configure b/gdb/configure index 64470a856ad..2fc0b583702 100755 --- a/gdb/configure +++ b/gdb/configure @@ -27743,6 +27743,45 @@ _ACEOF fi +# Check whether cfsetispeed/cfsetospeed accept arbitrary baud rates. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether cfsetispeed/cfsetospeed accept arbitrary baud rates" >&5 +$as_echo_n "checking whether cfsetispeed/cfsetospeed accept arbitrary baud rates... " >&6; } +if ${gdb_cv_cfsetspeed_arbitrary+:} false; then : + $as_echo_n "(cached) " >&6 +else + + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +int +main () +{ + + #if B9600 != 9600 + #error B-constants are not numeric symbols + #endif + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + gdb_cv_cfsetspeed_arbitrary=yes +else + gdb_cv_cfsetspeed_arbitrary=no +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gdb_cv_cfsetspeed_arbitrary" >&5 +$as_echo "$gdb_cv_cfsetspeed_arbitrary" >&6; } + +if test "$gdb_cv_cfsetspeed_arbitrary" = yes; then + +$as_echo "#define HAVE_CFSETSPEED_ARBITRARY 1" >>confdefs.h + +fi + # Check whether --with-jit-reader-dir was given. diff --git a/gdb/configure.ac b/gdb/configure.ac index 76a22c9cf3d..56ab86d9356 100644 --- a/gdb/configure.ac +++ b/gdb/configure.ac @@ -728,6 +728,25 @@ AC_SEARCH_LIBS(dlopen, dl) # Check for members required by the legacy Linux custom baud rate path. AC_CHECK_MEMBERS([struct termios.c_ospeed], [], [], [[#include ]]) +# Check whether cfsetispeed/cfsetospeed accept arbitrary baud rates. +AC_CACHE_CHECK([whether cfsetispeed/cfsetospeed accept arbitrary baud rates], + [gdb_cv_cfsetspeed_arbitrary], [ + AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM([[#include ]], + [[ + #if B9600 != 9600 + #error B-constants are not numeric symbols + #endif + ]])], + [gdb_cv_cfsetspeed_arbitrary=yes], + [gdb_cv_cfsetspeed_arbitrary=no]) +]) + +if test "$gdb_cv_cfsetspeed_arbitrary" = yes; then + AC_DEFINE([HAVE_CFSETSPEED_ARBITRARY], [1], + [Define if cfsetispeed/cfsetospeed accept arbitrary baud rates.]) +fi + GDB_AC_WITH_DIR([JIT_READER_DIR], [jit-reader-dir], [directory to load the JIT readers from], [${libdir}/gdb]) diff --git a/gdb/ser-unix.c b/gdb/ser-unix.c index 72c46d29e8f..1bb21a08572 100644 --- a/gdb/ser-unix.c +++ b/gdb/ser-unix.c @@ -55,9 +55,10 @@ #include "gdbsupport/scoped_ignore_sigttou.h" -#if (defined(HAVE_SYS_IOCTL_H) \ - && ((defined(BOTHER) && defined(HAVE_STRUCT_TERMIOS_C_OSPEED)) \ - || defined(IOSSIOSPEED))) +#if (defined(HAVE_CFSETSPEED_ARBITRARY) \ + || (defined(HAVE_SYS_IOCTL_H) \ + && ((defined(BOTHER) && defined(HAVE_STRUCT_TERMIOS_C_OSPEED)) \ + || defined(IOSSIOSPEED)))) # define HAVE_CUSTOM_BAUDRATE_SUPPORT 1 #endif @@ -510,7 +511,32 @@ set_baudcode_baudrate (struct serial *scb, int baud_code) perror_with_name (_("could not set tty state")); } -#if HAVE_CUSTOM_BAUDRATE_SUPPORT && defined(BOTHER) +#if HAVE_CUSTOM_BAUDRATE_SUPPORT && defined(HAVE_CFSETSPEED_ARBITRARY) + +/* Set a custom baud rate using the POSIX cfsetispeed/cfsetospeed + interface. Supported in glibc 2.42 and later and expected to be + standardized in a future POSIX revision. It is platform-agnostic + and also covers systems like GNU Hurd that do not provide BOTHER. */ + +static void +set_custom_baudrate_posix (int fd, int rate) +{ + struct termios tio; + + if (tcgetattr (fd, &tio) < 0) + perror_with_name (_("Cannot get current baud rate")); + + if (cfsetispeed (&tio, rate) < 0) + perror_with_name (_("Cannot set custom input baud rate")); + + if (cfsetospeed (&tio, rate) < 0) + perror_with_name (_("Cannot set custom output baud rate")); + + if (tcsetattr (fd, TCSANOW, &tio) < 0) + perror_with_name (_("Cannot set custom baud rate")); +} + +#elif HAVE_CUSTOM_BAUDRATE_SUPPORT && defined(BOTHER) /* Set a custom baud rate using the termios BOTHER. */ @@ -557,19 +583,24 @@ set_custom_baudrate_darwin (int fd, int rate) } #endif /* HAVE_CUSTOM_BAUDRATE_SUPPORT - && (defined(BOTHER) || defined(IOSSIOSPEED)) */ + && (defined(HAVE_CFSETSPEED_ARBITRARY) + || defined(BOTHER) + || defined(IOSSIOSPEED)) */ #if HAVE_CUSTOM_BAUDRATE_SUPPORT /* Set a baud rate that differs from the OS B_codes. - This is possible if one of the following macros is available: - - BOTHER (Linux). - - IOSSIOSPEED (Darwin). */ + Prefer the POSIX cfsetispeed/cfsetospeed interface when the host + libc accepts arbitrary baud rates. Otherwise fall back to + Linux-specific (BOTHER) or Darwin-specific (IOSSIOSPEED) + interfaces. */ static void set_custom_baudrate (int fd, int rate) { -#if defined(BOTHER) +#if defined(HAVE_CFSETSPEED_ARBITRARY) + set_custom_baudrate_posix (fd, rate); +#elif defined(BOTHER) set_custom_baudrate_linux (fd, rate); #elif defined(IOSSIOSPEED) set_custom_baudrate_darwin (fd, rate);