From: sunilkumar.dora@windriver.com
To: gdb-patches@sourceware.org
Cc: kevinb@redhat.com, macro@orcam.me.uk,
Randy.MacLeod@windriver.com, Sundeep.Kokkonda@windriver.com,
schwab@linux-m68k.org, tromey@sourceware.org, simark@simark.ca,
sunilkumar.dora@windriver.com
Subject: [PATCH V3] PR gdb/33747: gdb/ser-unix: modernize Linux custom baud rate support
Date: Thu, 12 Mar 2026 14:01:06 -0700 [thread overview]
Message-ID: <20260312210106.880833-1-sunilkumar.dora@windriver.com> (raw)
From: Sunil Dora <sunilkumar.dora@windriver.com>
The Linux custom baud rate implementation previously accessed the
struct termios members c_ispeed and c_ospeed directly. These fields
exist in glibc but are not exposed by musl, causing builds to fail on
musl-based systems.
Update set_custom_baudrate_linux to use a capability-based approach,
with three distinct code paths:
1) If POSIX cfsetispeed/cfsetospeed accept arbitrary baud rates
(HAVE_CFSETSPEED_ARBITRARY), use them to set input and output
speeds.
2) Else if Linux termios2 interface is available (TCGETS2/BOTHER),
use it to support arbitrary baud rates.
3) Else if legacy struct termios supports c_ispeed/c_ospeed, use
the TCGETS/TCSETS fallback (primarily for glibc on older
architectures).
4) Otherwise, emit an error indicating that custom baud rates are
unsupported on this platform.
This preserves existing behavior on glibc systems while restoring
build compatibility with musl and other libc implementations.
Suggested-by: Kevin Buettner <kevinb@redhat.com>
Suggested-by: Maciej W. Rozycki <macro@orcam.me.uk>
Signed-off-by: Sunil Dora <sunilkumar.dora@windriver.com>
---
**Changes since V2**
- Renamed Autoconf check to HAVE_CFSETSPEED_ARBITRARY
- Prefer POSIX cfsetispeed/cfsetospeed when arbitrary baud rates are supported
- Fall back to Linux termios2 (TCGETS2/BOTHER) interface if needed
- Retain legacy TCGETS fallback for glibc systems with c_ispeed/c_ospeed
- Simplified capability/fallback logic
- Replaced incorrect perror_with_name() with error()
gdb/NEWS | 4 ++++
gdb/config.in | 6 ++++++
gdb/configure | 52 +++++++++++++++++++++++++++++++++++++++++++++
gdb/configure.ac | 22 +++++++++++++++++++
gdb/ser-unix.c | 55 ++++++++++++++++++++++++++++++++++--------------
5 files changed, 123 insertions(+), 16 deletions(-)
diff --git a/gdb/NEWS b/gdb/NEWS
index e46a5108272..0c69da084de 100644
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -36,6 +36,10 @@
subsequent runs of the inferior will use the same arguments as the
first run.
+* GDB detects whether the host cfsetispeed/cfsetospeed functions accept
+ arbitrary baud rates. If not, GDB falls back to Linux-specific termios
+ interfaces to support custom baud rates.
+
* 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 b11fcf18372..b7aacab898a 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
@@ -517,6 +520,9 @@
/* Define to 1 if `st_blocks' is a member of `struct stat'. */
#undef HAVE_STRUCT_STAT_ST_BLOCKS
+/* Define to 1 if `c_ospeed' is a member of `struct termios'. */
+#undef HAVE_STRUCT_TERMIOS_C_OSPEED
+
/* Define to 1 if `td_pcb' is a member of `struct thread'. */
#undef HAVE_STRUCT_THREAD_TD_PCB
diff --git a/gdb/configure b/gdb/configure
index 12c54521682..ef2ee9f72ec 100755
--- a/gdb/configure
+++ b/gdb/configure
@@ -27728,6 +27728,58 @@ if test "$ac_res" != no; then :
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 <termios.h>
+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 for members required by the legacy Linux custom baud rate path.
+ac_fn_c_check_member "$LINENO" "struct termios" "c_ospeed" "ac_cv_member_struct_termios_c_ospeed" "#include <termios.h>
+"
+if test "x$ac_cv_member_struct_termios_c_ospeed" = xyes; then :
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_STRUCT_TERMIOS_C_OSPEED 1
+_ACEOF
+
+
+fi
+
+
# Check whether --with-jit-reader-dir was given.
diff --git a/gdb/configure.ac b/gdb/configure.ac
index cf8078e1d89..e558cf44703 100644
--- a/gdb/configure.ac
+++ b/gdb/configure.ac
@@ -725,6 +725,28 @@ AC_CONFIG_FILES([jit-reader.h:jit-reader.in])
AC_SEARCH_LIBS(dlopen, dl)
+# 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 <termios.h>]],
+ [[
+ #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
+
+# Check for members required by the legacy Linux custom baud rate path.
+AC_CHECK_MEMBERS([struct termios.c_ospeed], [], [], [[#include <termios.h>]])
+
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 c295a9c5ba1..a15f4cc2162 100644
--- a/gdb/ser-unix.c
+++ b/gdb/ser-unix.c
@@ -510,36 +510,59 @@ set_baudcode_baudrate (struct serial *scb, int baud_code)
#if HAVE_CUSTOM_BAUDRATE_SUPPORT && defined(BOTHER)
-/* Set a custom baud rate using the termios BOTHER. */
+/* Set a custom baud rate.
+
+ Prefer the POSIX cfsetispeed/cfsetospeed interface when it accepts
+ arbitrary baud rates. Otherwise fall back to Linux-specific termios2
+ (BOTHER) or legacy termios interfaces. */
static void
set_custom_baudrate_linux (int fd, int rate)
{
-#ifdef TCGETS2
- struct termios2 tio;
- const unsigned long req_get = TCGETS2;
- const unsigned long req_set = TCSETS2;
-#else
+#if defined(HAVE_CFSETSPEED_ARBITRARY)
struct termios tio;
- const unsigned long req_get = TCGETS;
- const unsigned long req_set = TCSETS;
-#endif
+ if (tcgetattr (fd, &tio) < 0)
+ perror_with_name (_("Cannot get current baud rate"));
+
+ cfsetispeed (&tio, rate);
+ cfsetospeed (&tio, rate);
+
+ if (tcsetattr (fd, TCSANOW, &tio) < 0)
+ perror_with_name (_("Cannot set custom baud rate"));
+
+#elif defined(TCGETS2)
+ struct termios2 tio2;
+ if (ioctl (fd, TCGETS2, &tio2) < 0)
+ perror_with_name (_("Cannot get current baud rate"));
+
+ tio2.c_cflag &= ~CBAUD;
+ tio2.c_cflag |= BOTHER;
+ tio2.c_ospeed = rate;
+ tio2.c_cflag &= ~(CBAUD << IBSHIFT);
+ tio2.c_cflag |= BOTHER << IBSHIFT;
+ tio2.c_ispeed = rate;
- if (ioctl (fd, req_get, &tio) < 0)
- perror_with_name (_("Can not get current baud rate"));
+ if (ioctl (fd, TCSETS2, &tio2) < 0)
+ perror_with_name (_("Cannot set custom baud rate"));
+
+#elif defined(HAVE_STRUCT_TERMIOS_C_OSPEED)
+ struct termios tio;
+ if (ioctl (fd, TCGETS, &tio) < 0)
+ perror_with_name (_("Cannot get current baud rate"));
- /* Clear the current output baud rate and fill a new value. */
tio.c_cflag &= ~CBAUD;
tio.c_cflag |= BOTHER;
tio.c_ospeed = rate;
-
- /* Clear the current input baud rate and fill a new value. */
tio.c_cflag &= ~(CBAUD << IBSHIFT);
tio.c_cflag |= BOTHER << IBSHIFT;
tio.c_ispeed = rate;
- if (ioctl (fd, req_set, &tio) < 0)
- perror_with_name (_("Can not set custom baud rate"));
+ if (ioctl (fd, TCSETS, &tio) < 0)
+ perror_with_name (_("Cannot set custom baud rate"));
+
+#else
+ error (_("Custom baud rate not supported on this platform"));
+#endif
}
#elif HAVE_CUSTOM_BAUDRATE_SUPPORT && defined(IOSSIOSPEED)
--
2.49.0
next reply other threads:[~2026-03-12 21:02 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-03-12 21:01 sunilkumar.dora [this message]
2026-03-19 22:44 ` Kevin Buettner
2026-03-22 19:49 ` Sunil Kumar Dora
2026-03-20 1:24 ` Maciej W. Rozycki
2026-03-22 19:55 ` Sunil Kumar Dora
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260312210106.880833-1-sunilkumar.dora@windriver.com \
--to=sunilkumar.dora@windriver.com \
--cc=Randy.MacLeod@windriver.com \
--cc=Sundeep.Kokkonda@windriver.com \
--cc=gdb-patches@sourceware.org \
--cc=kevinb@redhat.com \
--cc=macro@orcam.me.uk \
--cc=schwab@linux-m68k.org \
--cc=simark@simark.ca \
--cc=tromey@sourceware.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox