[PATCHv6,2/2] gdb: unix: allow to use custom baud rate
Checks
Context |
Check |
Description |
linaro-tcwg-bot/tcwg_gdb_build--master-aarch64 |
success
|
Build passed
|
linaro-tcwg-bot/tcwg_gdb_build--master-arm |
success
|
Build passed
|
linaro-tcwg-bot/tcwg_gdb_check--master-aarch64 |
success
|
Test passed
|
linaro-tcwg-bot/tcwg_gdb_check--master-arm |
success
|
Test passed
|
Commit Message
Modern unix systems allow to set custom baud rate instead of predefined in termios.h.
- To use this in Linux it must have BOTHER macro in "asm/termio.h"
- MacOS could handle this using IOSSIOSPEED passed to ioctl()
---
gdb/config.in | 6 +++
gdb/configure | 2 +
gdb/configure.ac | 2 +
gdb/ser-unix.c | 136 ++++++++++++++++++++++++++++++++++++++++++++---
4 files changed, 139 insertions(+), 7 deletions(-)
--
2.43.0
Comments
> +/* Workaround to resolve conflicting declarations of termios
> + * in <asm/termbits.h> and <termios.h>. */
Remove the leading * on the second line:
/* Workaround to resolve conflicting declarations of termios
in <asm/termbits.h> and <termios.h>. */
With those nits fixed, the series LGTM:
Approved-By: Simon Marchi <simon.marchi@efficios.com>
Do you have push access already? If not, you have the choice. If you
intend on contributing regularly, you can get push access, otherwise I
can push the series for you.
Simon
On Wed, 9 Apr 2025, Alexey Lapshin wrote:
> Modern unix systems allow to set custom baud rate instead of predefined
> in termios.h.
>
> - To use this in Linux it must have BOTHER macro in "asm/termio.h"
> - MacOS could handle this using IOSSIOSPEED passed to ioctl()
FYI, this is now being sorted properly for Linux hosts in glibc[1], so no
such hacks as here will eventually be needed.
References:
[1] "Trying again for termios sanity on Linux",
<https://inbox.sourceware.org/libc-alpha/f91ce7ff-7816-4d68-a648-210ee43ebc77@zytor.com/>
Maciej
@@ -93,6 +93,9 @@
/* Define if amd-dbgapi is being linked in. */
#undef HAVE_AMD_DBGAPI
+/* Define to 1 if you have the <asm/termios.h> header file. */
+#undef HAVE_ASM_TERMIOS_H
+
/* Define to 1 if you have the `btowc' function. */
#undef HAVE_BTOWC
@@ -244,6 +247,9 @@
/* Define to 1 if you have the <inttypes.h> header file. */
#undef HAVE_INTTYPES_H
+/* Define to 1 if you have the <IOKit/serial/ioss.h> header file. */
+#undef HAVE_IOKIT_SERIAL_IOSS_H
+
/* Define to 1 if you have the `kinfo_getfile' function. */
#undef HAVE_KINFO_GETFILE
@@ -29239,6 +29239,8 @@ $as_echo "#define STDC_HEADERS 1" >>confdefs.h
fi
for ac_header in \
+ IOKit/serial/ioss.h \
+ asm/termios.h \
machine/reg.h \
nlist.h \
ptrace.h \
@@ -1330,6 +1330,8 @@ AC_SUBST(SRCHIGH_CFLAGS)
AC_HEADER_STDC
AC_CHECK_HEADERS([ \
+ IOKit/serial/ioss.h \
+ asm/termios.h \
machine/reg.h \
nlist.h \
ptrace.h \
@@ -30,9 +30,33 @@
#include "gdbsupport/gdb_select.h"
#include "cli/cli-cmds.h"
#include "gdbsupport/filestuff.h"
-#include <termios.h>
+
+#ifdef HAVE_SYS_IOCTL_H
+# include <sys/ioctl.h>
+#endif
+
+#if HAVE_IOKIT_SERIAL_IOSS_H
+# include <IOKit/serial/ioss.h>
+#endif
+
+#if HAVE_ASM_TERMIOS_H
+/* Workaround to resolve conflicting declarations of termios
+ * in <asm/termbits.h> and <termios.h>. */
+# define termios asmtermios
+# include <asm/termbits.h>
+# undef termios
+#endif
+
+#ifdef HAVE_TERMIOS_H
+# include <termios.h>
+#endif
+
#include "gdbsupport/scoped_ignore_sigttou.h"
+#if defined(HAVE_SYS_IOCTL_H) && (defined(BOTHER) || defined(IOSSIOSPEED))
+# define HAVE_CUSTOM_BAUDRATE_SUPPORT 1
+#endif
+
struct hardwire_ttystate
{
struct termios termios;
@@ -436,6 +460,7 @@ rate_to_code (int rate)
/* check if it is in between valid values. */
if (rate < baudtab[i].rate)
{
+#if !HAVE_CUSTOM_BAUDRATE_SUPPORT
if (i)
{
error (_("Invalid baud rate %d. "
@@ -447,29 +472,126 @@ rate_to_code (int rate)
error (_("Invalid baud rate %d. Minimum value is %d."),
rate, baudtab[0].rate);
}
+#else
+ return -1;
+#endif
}
}
}
-
+
+#if !HAVE_CUSTOM_BAUDRATE_SUPPORT
/* The requested speed was too large. */
error (_("Invalid baud rate %d. Maximum value is %d."),
rate, baudtab[i - 1].rate);
+#else
+ return -1;
+#endif
}
+/* Set baud rate using B_code from termios.h. */
+
static void
-hardwire_setbaudrate (struct serial *scb, int rate)
+set_baudcode_baudrate (struct serial *scb, int baud_code)
{
struct hardwire_ttystate state;
- int baud_code = rate_to_code (rate);
-
+
if (get_tty_state (scb, &state))
- perror_with_name ("could not get tty state");
+ perror_with_name (_("could not get tty state"));
cfsetospeed (&state.termios, baud_code);
cfsetispeed (&state.termios, baud_code);
if (set_tty_state (scb, &state))
- perror_with_name ("could not set tty state");
+ perror_with_name (_("could not set tty state"));
+}
+
+#if HAVE_CUSTOM_BAUDRATE_SUPPORT && defined(BOTHER)
+
+/* Set a custom baud rate using the termios BOTHER. */
+
+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
+ struct termios tio;
+ const unsigned long req_get = TCGETS;
+ const unsigned long req_set = TCSETS;
+#endif
+
+ if (ioctl (fd, req_get, &tio) < 0)
+ perror_with_name (_("Can not 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"));
+}
+
+#elif HAVE_CUSTOM_BAUDRATE_SUPPORT && defined(IOSSIOSPEED)
+
+/* Set a custom baud rate using the IOSSIOSPEED ioctl call. */
+
+static void
+set_custom_baudrate_darwin (int fd, int rate)
+{
+
+ if (ioctl (fd, IOSSIOSPEED, &rate) < 0)
+ perror_with_name (_("Can not set custom baud rate"));
+}
+
+#endif /* HAVE_CUSTOM_BAUDRATE_SUPPORT
+ && (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). */
+
+static void
+set_custom_baudrate (int fd, int rate)
+{
+#if defined(BOTHER)
+ set_custom_baudrate_linux (fd, rate);
+#elif defined(IOSSIOSPEED)
+ set_custom_baudrate_darwin (fd, rate);
+#endif
+}
+
+#endif /* HAVE_CUSTOM_BAUDRATE_SUPPORT */
+
+/* Set the baud rate for the serial communication. */
+
+static void
+hardwire_setbaudrate (struct serial *scb, int rate)
+{
+ int baud_code = rate_to_code (rate);
+
+ if (baud_code < 0)
+ {
+#if HAVE_CUSTOM_BAUDRATE_SUPPORT
+ set_custom_baudrate (scb->fd, rate);
+#else
+ /* An error should already have been thrown by rate_to_code().
+ Add an additional error in case execution somehow reaches this line. */
+ gdb_assert_not_reached (_("Serial baud rate was not found in B_codes"));
+#endif
+ }
+ else
+ set_baudcode_baudrate (scb, baud_code);
}
static int