commit:     8b9885718d31543b91b1a817c22a16dfbabe3571
Author:     Sam James <sam <AT> gentoo <DOT> org>
AuthorDate: Sun Sep 14 06:24:20 2025 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Sun Sep 14 06:25:27 2025 +0000
URL:        https://gitweb.gentoo.org/repo/gentoo.git/commit/?id=8b988571

dev-libs/libserialport: fix compat w/ glibc-2.42 (termios changes)

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 <AT> gentoo.org>

 .../libserialport-0.1.2-termios-glibc-2.42-1.patch |  32 +++
 .../libserialport-0.1.2-termios-glibc-2.42-2.patch |  43 ++++
 .../libserialport-0.1.2-termios-glibc-2.42-3.patch | 233 +++++++++++++++++++++
 ...t-9999.ebuild => libserialport-0.1.2-r1.ebuild} |  15 +-
 dev-libs/libserialport/libserialport-9999.ebuild   |  15 +-
 5 files changed, 334 insertions(+), 4 deletions(-)

diff --git 
a/dev-libs/libserialport/files/libserialport-0.1.2-termios-glibc-2.42-1.patch 
b/dev-libs/libserialport/files/libserialport-0.1.2-termios-glibc-2.42-1.patch
new file mode 100644
index 000000000000..48ae2b2d957f
--- /dev/null
+++ 
b/dev-libs/libserialport/files/libserialport-0.1.2-termios-glibc-2.42-1.patch
@@ -0,0 +1,32 @@
+https://bugs.gentoo.org/962830
+https://sourceware.org/bugzilla/show_bug.cgi?id=33340#c22
+
+From c24f68c1028b30364acb4ed085de15364fddbcb9 Mon Sep 17 00:00:00 2001
+From: "H. Peter Anvin" <[email protected]>
+Date: Wed, 10 Sep 2025 17:58:01 -0700
+Subject: [PATCH 1/3] linux_termios: clear CIBAUD flags, too
+
+In case the serial port was already set up with split speed, using one
+of the standard speed constants (i.e. not BOTHER) it is necessary to
+clear CIBAUD to revert back to single speed.
+
+Signed-off-by: H. Peter Anvin <[email protected]>
+---
+ linux_termios.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/linux_termios.c b/linux_termios.c
+index 3630e5758ae3..0dd0b105726f 100644
+--- a/linux_termios.c
++++ b/linux_termios.c
+@@ -86,7 +86,7 @@ SP_PRIV void set_termios_speed(void *data, int speed)
+ #else
+       struct termios *term = (struct termios *) data;
+ #endif
+-      term->c_cflag &= ~CBAUD;
++      term->c_cflag &= ~(CBAUD | CIBAUD);
+       term->c_cflag |= BOTHER;
+       term->c_ispeed = term->c_ospeed = speed;
+ }
+-- 
+2.51.0

diff --git 
a/dev-libs/libserialport/files/libserialport-0.1.2-termios-glibc-2.42-2.patch 
b/dev-libs/libserialport/files/libserialport-0.1.2-termios-glibc-2.42-2.patch
new file mode 100644
index 000000000000..c311be0b882d
--- /dev/null
+++ 
b/dev-libs/libserialport/files/libserialport-0.1.2-termios-glibc-2.42-2.patch
@@ -0,0 +1,43 @@
+https://bugs.gentoo.org/962830
+https://sourceware.org/bugzilla/show_bug.cgi?id=33340#c23
+
+From 02caf0c979fee9bfdac47dccbfb8147f8b8128eb Mon Sep 17 00:00:00 2001
+From: "H. Peter Anvin" <[email protected]>
+Date: Wed, 10 Sep 2025 17:59:54 -0700
+Subject: [PATCH 2/3] termios: read output speed, not input speed
+
+POSIX is pretty clear that if only one speed is supported, it is the
+output speed setting that counts. On some platforms, the input speed
+can even end up being reported as 0 for single speed configuration.
+
+Thus, look at the output speed setting, not the input speed setting.
+
+Signed-off-by: H. Peter Anvin <[email protected]>
+---
+ serialport.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/serialport.c b/serialport.c
+index b3b9249a37c7..392ec61e95f2 100644
+--- a/serialport.c
++++ b/serialport.c
+@@ -1812,7 +1812,7 @@ static enum sp_return get_config(struct sp_port *port, 
struct port_data *data,
+ #endif
+ 
+       for (i = 0; i < NUM_STD_BAUDRATES; i++) {
+-              if (cfgetispeed(&data->term) == std_baudrates[i].index) {
++              if (cfgetospeed(&data->term) == std_baudrates[i].index) {
+                       config->baudrate = std_baudrates[i].value;
+                       break;
+               }
+@@ -1820,7 +1820,7 @@ static enum sp_return get_config(struct sp_port *port, 
struct port_data *data,
+ 
+       if (i == NUM_STD_BAUDRATES) {
+ #ifdef __APPLE__
+-              config->baudrate = (int)data->term.c_ispeed;
++              config->baudrate = (int)data->term.c_ospeed;
+ #elif defined(USE_TERMIOS_SPEED)
+               TRY(get_baudrate(port->fd, &config->baudrate));
+ #else
+-- 
+2.51.0

diff --git 
a/dev-libs/libserialport/files/libserialport-0.1.2-termios-glibc-2.42-3.patch 
b/dev-libs/libserialport/files/libserialport-0.1.2-termios-glibc-2.42-3.patch
new file mode 100644
index 000000000000..200b83826b67
--- /dev/null
+++ 
b/dev-libs/libserialport/files/libserialport-0.1.2-termios-glibc-2.42-3.patch
@@ -0,0 +1,233 @@
+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" <[email protected]>
+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 <[email protected]>
+---
+ 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

diff --git a/dev-libs/libserialport/libserialport-9999.ebuild 
b/dev-libs/libserialport/libserialport-0.1.2-r1.ebuild
similarity index 68%
copy from dev-libs/libserialport/libserialport-9999.ebuild
copy to dev-libs/libserialport/libserialport-0.1.2-r1.ebuild
index 2c6c09844ca1..943e136cd815 100644
--- a/dev-libs/libserialport/libserialport-9999.ebuild
+++ b/dev-libs/libserialport/libserialport-0.1.2-r1.ebuild
@@ -3,9 +3,11 @@
 
 EAPI="8"
 
+inherit autotools
+
 if [[ ${PV} == "9999" ]]; then
        EGIT_REPO_URI="https://github.com/sigrokproject/${PN}.git";
-       inherit autotools git-r3
+       inherit git-r3
 else
        SRC_URI="https://sigrok.org/download/source/${PN}/${P}.tar.gz";
        KEYWORDS="~amd64 ~arm ~arm64 ~riscv ~x86"
@@ -20,10 +22,19 @@ IUSE="static-libs"
 
 BDEPEND="virtual/pkgconfig"
 
+PATCHES=(
+       "${FILESDIR}"/${PN}-0.1.2-termios-glibc-2.42-1.patch
+       "${FILESDIR}"/${PN}-0.1.2-termios-glibc-2.42-2.patch
+       "${FILESDIR}"/${PN}-0.1.2-termios-glibc-2.42-3.patch
+)
+
 src_prepare() {
        default
 
-       [[ ${PV} == "9999" ]] && eautoreconf
+       #[[ ${PV} == "9999" ]] && eautoreconf
+
+       # Unconditional eautoreconf for glibc-2.42 patches
+       eautoreconf
 }
 
 src_configure() {

diff --git a/dev-libs/libserialport/libserialport-9999.ebuild 
b/dev-libs/libserialport/libserialport-9999.ebuild
index 2c6c09844ca1..943e136cd815 100644
--- a/dev-libs/libserialport/libserialport-9999.ebuild
+++ b/dev-libs/libserialport/libserialport-9999.ebuild
@@ -3,9 +3,11 @@
 
 EAPI="8"
 
+inherit autotools
+
 if [[ ${PV} == "9999" ]]; then
        EGIT_REPO_URI="https://github.com/sigrokproject/${PN}.git";
-       inherit autotools git-r3
+       inherit git-r3
 else
        SRC_URI="https://sigrok.org/download/source/${PN}/${P}.tar.gz";
        KEYWORDS="~amd64 ~arm ~arm64 ~riscv ~x86"
@@ -20,10 +22,19 @@ IUSE="static-libs"
 
 BDEPEND="virtual/pkgconfig"
 
+PATCHES=(
+       "${FILESDIR}"/${PN}-0.1.2-termios-glibc-2.42-1.patch
+       "${FILESDIR}"/${PN}-0.1.2-termios-glibc-2.42-2.patch
+       "${FILESDIR}"/${PN}-0.1.2-termios-glibc-2.42-3.patch
+)
+
 src_prepare() {
        default
 
-       [[ ${PV} == "9999" ]] && eautoreconf
+       #[[ ${PV} == "9999" ]] && eautoreconf
+
+       # Unconditional eautoreconf for glibc-2.42 patches
+       eautoreconf
 }
 
 src_configure() {

Reply via email to