mirror of
https://github.com/gentoo-mirror/gentoo.git
synced 2025-12-22 00:00:56 +03:00
Pull in hpa's patches from https://github.com/hpax/libserialport. He's sent them upstream but I think sigrok are having some infra issues. Bug: https://sourceware.org/PR33340 Closes: https://bugs.gentoo.org/962830 Signed-off-by: Sam James <sam@gentoo.org>
234 lines
8.1 KiB
Diff
234 lines
8.1 KiB
Diff
https://bugs.gentoo.org/962830
|
|
https://sourceware.org/bugzilla/show_bug.cgi?id=33340#c24
|
|
|
|
From f051e30dff057a7304a6c94a942da9a09740851d Mon Sep 17 00:00:00 2001
|
|
From: "H. Peter Anvin" <hpa@zytor.com>
|
|
Date: Wed, 10 Sep 2025 18:01:48 -0700
|
|
Subject: [PATCH 3/3] termios: check to see if termios speed_t is a direct map
|
|
to baud
|
|
|
|
If termios speed_t is a direct mapping to bauds, it is presumably safe
|
|
to assume that it can be used as a generic interface. This applies to
|
|
Linux with glibc 2.42+, GNU Hurd, and at least some BSDs.
|
|
|
|
Try to detect this case and if so, do the simple thing.
|
|
|
|
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
|
|
---
|
|
configure.ac | 56 +++++++++++++++++++++++++++++++++++++++-
|
|
libserialport_internal.h | 7 +++--
|
|
linux_termios.c | 12 ++++++---
|
|
serialport.c | 19 +++++++++++++-
|
|
4 files changed, 86 insertions(+), 8 deletions(-)
|
|
|
|
diff --git a/configure.ac b/configure.ac
|
|
index d71833fea141..ae6406e5e08b 100644
|
|
--- a/configure.ac
|
|
+++ b/configure.ac
|
|
@@ -111,6 +111,60 @@ AC_SYS_LARGEFILE
|
|
# Define size_t if not defined as standard.
|
|
AC_TYPE_SIZE_T
|
|
|
|
+# Check to see if the baud rates in termios.h seem sane.
|
|
+AC_CACHE_CHECK([if <termios.h> is sane], [sp_cv_termios_sane], [
|
|
+ AC_COMPILE_IFELSE([AC_LANG_SOURCE([[
|
|
+#include <termios.h>
|
|
+#if (!defined(B0) || B0 == 0) \
|
|
+ && (!defined(B50) || B50 == 50) \
|
|
+ && (!defined(B75) || B75 == 75) \
|
|
+ && (!defined(B110) || B110 == 110) \
|
|
+ && (!defined(B134) || B134 == 134) \
|
|
+ && (!defined(B150) || B150 == 150) \
|
|
+ && (!defined(B200) || B200 == 200) \
|
|
+ && (!defined(B300) || B300 == 300) \
|
|
+ && (!defined(B600) || B600 == 600) \
|
|
+ && (!defined(B1200) || B1200 == 1200) \
|
|
+ && (!defined(B1800) || B1800 == 1800) \
|
|
+ && (!defined(B2400) || B2400 == 2400) \
|
|
+ && (!defined(B4800) || B4800 == 4800) \
|
|
+ && (!defined(B7200) || B7200 == 7200) \
|
|
+ && (!defined(B9600) || B9600 == 9600) \
|
|
+ && (!defined(B14400) || B14400 == 14400) \
|
|
+ && (!defined(B19200) || B19200 == 19200) \
|
|
+ && (!defined(B28800) || B28800 == 28800) \
|
|
+ && (!defined(B33600) || B33600 == 33600) \
|
|
+ && (!defined(B38400) || B38400 == 38400) \
|
|
+ && (!defined(B57600) || B57600 == 57600) \
|
|
+ && (!defined(B76800) || B76800 == 76800) \
|
|
+ && (!defined(B115200) || B115200 == 115200) \
|
|
+ && (!defined(B153600) || B153600 == 153600) \
|
|
+ && (!defined(B230400) || B230400 == 230400) \
|
|
+ && (!defined(B307200) || B307200 == 307200) \
|
|
+ && (!defined(B460800) || B460800 == 460800) \
|
|
+ && (!defined(B500000) || B500000 == 500000) \
|
|
+ && (!defined(B576000) || B576000 == 576000) \
|
|
+ && (!defined(B614400) || B614400 == 614400) \
|
|
+ && (!defined(B921600) || B921600 == 921600) \
|
|
+ && (!defined(B1000000) || B1000000 == 1000000) \
|
|
+ && (!defined(B1152000) || B1152000 == 1152000) \
|
|
+ && (!defined(B1500000) || B1500000 == 1500000) \
|
|
+ && (!defined(B2000000) || B2000000 == 2000000) \
|
|
+ && (!defined(B2500000) || B2500000 == 2500000) \
|
|
+ && (!defined(B3000000) || B3000000 == 3000000) \
|
|
+ && (!defined(B3500000) || B3500000 == 3500000) \
|
|
+ && (!defined(B4000000) || B4000000 == 4000000) \
|
|
+ && (!defined(B5000000) || B5000000 == 5000000) \
|
|
+ && (!defined(B10000000) || B10000000 == 10000000)
|
|
+# define TERMIOS_SPEED_T_SANE 1
|
|
+#else
|
|
+# error "<termios.h> uses stupid constants"
|
|
+#endif
|
|
+]])], [sp_cv_termios_sane=yes], [sp_cv_termios_sane=no])])
|
|
+
|
|
+AS_IF([test x$sp_cv_termios_sane = xyes],
|
|
+[AC_DEFINE(HAVE_SANE_TERMIOS, 1, [<termios.h> speeds are sane])],
|
|
+[
|
|
# Check for specific termios structures.
|
|
AC_CHECK_TYPES([struct termios2],,,
|
|
[[#include <linux/termios.h>]])
|
|
@@ -121,7 +175,7 @@ AC_CHECK_MEMBERS([struct termios.c_ispeed, struct termios.c_ospeed,
|
|
# Check for the BOTHER definition, needed for setting arbitrary baud rates.
|
|
# We can't just #ifdef BOTHER in the code, because of the separation between
|
|
# code using libc headers and code using kernel termios.h headers.
|
|
-AC_CHECK_DECLS([BOTHER],,, [[#include <linux/termios.h>]])
|
|
+AC_CHECK_DECLS([BOTHER],,, [[#include <linux/termios.h>]])])
|
|
|
|
# Check for serial_struct.
|
|
AC_CHECK_TYPES([struct serial_struct],,, [[#include <linux/serial.h>]])
|
|
diff --git a/libserialport_internal.h b/libserialport_internal.h
|
|
index 57346d653ad3..88bb9f60b06b 100644
|
|
--- a/libserialport_internal.h
|
|
+++ b/libserialport_internal.h
|
|
@@ -130,8 +130,11 @@
|
|
#endif
|
|
|
|
/* Non-standard baudrates are not available everywhere. */
|
|
-#if (defined(HAVE_TERMIOS_SPEED) || defined(HAVE_TERMIOS2_SPEED)) && HAVE_DECL_BOTHER
|
|
-#define USE_TERMIOS_SPEED
|
|
+#ifdef HAVE_SANE_TERMIOS
|
|
+/* Directly supported by termios */
|
|
+# undef USE_TERMIOS_SPEED
|
|
+#elif (defined(HAVE_TERMIOS_SPEED) || defined(HAVE_TERMIOS2_SPEED)) && HAVE_DECL_BOTHER
|
|
+# define USE_TERMIOS_SPEED
|
|
#endif
|
|
|
|
struct sp_port {
|
|
diff --git a/linux_termios.c b/linux_termios.c
|
|
index 0dd0b105726f..dad0e9cb4208 100644
|
|
--- a/linux_termios.c
|
|
+++ b/linux_termios.c
|
|
@@ -18,10 +18,10 @@
|
|
*/
|
|
|
|
/*
|
|
- * At the time of writing, glibc does not support the Linux kernel interfaces
|
|
- * for setting non-standard baud rates and flow control. We therefore have to
|
|
- * prepare the correct ioctls ourselves, for which we need the declarations in
|
|
- * linux/termios.h.
|
|
+ * glibc before version 2.42 does not support the Linux kernel
|
|
+ * interfaces for setting non-standard baud rates and flow control. We
|
|
+ * therefore have to prepare the correct ioctls ourselves, for which
|
|
+ * we need the declarations in linux/termios.h.
|
|
*
|
|
* We can't include linux/termios.h in serialport.c however, because its
|
|
* contents conflict with the termios.h provided by glibc. So this file exists
|
|
@@ -38,6 +38,8 @@
|
|
#include <linux/termios.h>
|
|
#include "linux_termios.h"
|
|
|
|
+#ifndef HAVE_SANE_TERMIOS
|
|
+
|
|
SP_PRIV unsigned long get_termios_get_ioctl(void)
|
|
{
|
|
#ifdef HAVE_STRUCT_TERMIOS2
|
|
@@ -127,3 +129,5 @@ SP_PRIV void set_termiox_flow(void *data, int rts, int cts, int dtr, int dsr)
|
|
termx->x_cflag |= DSRXON;
|
|
}
|
|
#endif
|
|
+
|
|
+#endif
|
|
diff --git a/serialport.c b/serialport.c
|
|
index 392ec61e95f2..f1279cff87ca 100644
|
|
--- a/serialport.c
|
|
+++ b/serialport.c
|
|
@@ -23,6 +23,7 @@
|
|
|
|
#include "libserialport_internal.h"
|
|
|
|
+#ifndef HAVE_SANE_TERMIOS
|
|
static const struct std_baudrate std_baudrates[] = {
|
|
#ifdef _WIN32
|
|
/*
|
|
@@ -42,8 +43,8 @@ static const struct std_baudrate std_baudrates[] = {
|
|
#endif
|
|
#endif
|
|
};
|
|
-
|
|
#define NUM_STD_BAUDRATES ARRAY_SIZE(std_baudrates)
|
|
+#endif
|
|
|
|
void (*sp_debug_handler)(const char *format, ...) = sp_default_debug_handler;
|
|
|
|
@@ -1692,7 +1693,9 @@ static enum sp_return set_flow(int fd, struct port_data *data)
|
|
static enum sp_return get_config(struct sp_port *port, struct port_data *data,
|
|
struct sp_port_config *config)
|
|
{
|
|
+#ifndef HAVE_SANE_TERMIOS
|
|
unsigned int i;
|
|
+#endif
|
|
|
|
TRACE("%p, %p, %p", port, data, config);
|
|
|
|
@@ -1811,6 +1814,9 @@ static enum sp_return get_config(struct sp_port *port, struct port_data *data,
|
|
data->termiox_supported = 0;
|
|
#endif
|
|
|
|
+#ifdef HAVE_SANE_TERMIOS
|
|
+ config->baudrate = cfgetospeed(&data->term);
|
|
+#else
|
|
for (i = 0; i < NUM_STD_BAUDRATES; i++) {
|
|
if (cfgetospeed(&data->term) == std_baudrates[i].index) {
|
|
config->baudrate = std_baudrates[i].value;
|
|
@@ -1827,6 +1833,7 @@ static enum sp_return get_config(struct sp_port *port, struct port_data *data,
|
|
config->baudrate = -1;
|
|
#endif
|
|
}
|
|
+#endif
|
|
|
|
switch (data->term.c_cflag & CSIZE) {
|
|
case CS8:
|
|
@@ -1898,7 +1905,10 @@ static enum sp_return get_config(struct sp_port *port, struct port_data *data,
|
|
static enum sp_return set_config(struct sp_port *port, struct port_data *data,
|
|
const struct sp_port_config *config)
|
|
{
|
|
+#ifndef HAVE_SANE_TERMIOS
|
|
unsigned int i;
|
|
+#endif
|
|
+
|
|
#ifdef __APPLE__
|
|
BAUD_TYPE baud_nonstd;
|
|
|
|
@@ -2064,6 +2074,12 @@ static enum sp_return set_config(struct sp_port *port, struct port_data *data,
|
|
int controlbits;
|
|
|
|
if (config->baudrate >= 0) {
|
|
+#ifdef HAVE_SANE_TERMIOS
|
|
+ if (cfsetospeed(&data->term, config->baudrate) < 0)
|
|
+ RETURN_FAIL("cfsetospeed() failed");
|
|
+ if (cfsetispeed(&data->term, config->baudrate) < 0)
|
|
+ RETURN_FAIL("cfsetispeed() failed");
|
|
+#else
|
|
for (i = 0; i < NUM_STD_BAUDRATES; i++) {
|
|
if (config->baudrate == std_baudrates[i].value) {
|
|
if (cfsetospeed(&data->term, std_baudrates[i].index) < 0)
|
|
@@ -2088,6 +2104,7 @@ static enum sp_return set_config(struct sp_port *port, struct port_data *data,
|
|
RETURN_ERROR(SP_ERR_SUPP, "Non-standard baudrate not supported");
|
|
#endif
|
|
}
|
|
+#endif
|
|
}
|
|
|
|
if (config->bits >= 0) {
|
|
--
|
|
2.51.0
|