You are not logged in.
Yep, broken.
Offline
$ git bisect bad
5cf101a85aae0d703cdd8ed7b25fe288e41fdacb is the first bad commit
commit 5cf101a85aae0d703cdd8ed7b25fe288e41fdacb (HEAD)
Author: H. Peter Anvin (Intel) <hpa@zytor.com>
Date: Wed Jun 11 18:35:36 2025 -0700
linux: implement arbitrary and split speeds in termios
Linux has supported arbitrary speeds and split speeds in the kernel
since 2008 on all platforms except Alpha (fixed in 2020), but glibc
was never updated to match. This is further complicated by POSIX uses
of macros for the cf[gs]et[io]speed interfaces, rather than plain
numbers, as it really ought to have.
On most platforms, the glibc ABI includes the c_[io]speed fields in
struct termios, but they are incorrectly used. On MIPS and SPARC, they
are entirely missing.
For backwards compatibility, the kernel will still use the legacy
speed fields unless they are set to BOTHER, and will use the legacy
output speed as the input speed if the latter is 0 (== B0). However,
the specific encoding used is visible to user space applications,
including ones other than the one running.
- SPARC and MIPS get a new struct termios, and tc[gs]etattr() is
versioned accordingly. However, the new struct termios is set to be
a strict extension of the old one, which means that cf* interfaces
other than the speed-related ones do not need versioning.
- The Bxxx constants are redefined as equivalent to their integer
values and the legacy Bxxx constants are renamed __Bxxx.
- cf[gs]et[io]speed() and cfsetspeed() are versioned accordingly.
- tcgetattr() and cfset[io]speed() are adjusted to always keep the
c_[io]speed fields correct (unlike earlier versions), but to
canonicalize the representation to ALSO configure the legacy fields
if a valid legacy representation exists.
- tcsetattr(), too, canonicalizes the representation in this way
before passing it to the kernel, to maximize compatibility with
older applications/tools.
- The old IBAUD0 hack is removed; it is no longer necessary since
even the legacy c_cflag baud rate fields have had separate input
values for a long time.
Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
NEWS | 4 ++
sysdeps/unix/sysv/linux/Versions | 7 ++
sysdeps/unix/sysv/linux/aarch64/libc.abilist | 5 ++
sysdeps/unix/sysv/linux/alpha/bits/termios-c_cflag.h | 2 +
sysdeps/unix/sysv/linux/alpha/bits/{termios-baud.h => termios-cbaud.h} | 43 ++++++-------
sysdeps/unix/sysv/linux/alpha/kernel-features.h | 11 ++++
sysdeps/unix/sysv/linux/alpha/kernel_termios.h | 43 -------------
sysdeps/unix/sysv/linux/alpha/libc.abilist | 5 ++
sysdeps/unix/sysv/linux/{mips/bits/termios-struct.h => alpha/termios_arch.h} | 26 +++-----
sysdeps/unix/sysv/linux/arc/libc.abilist | 5 ++
sysdeps/unix/sysv/linux/arm/be/libc.abilist | 5 ++
sysdeps/unix/sysv/linux/arm/le/libc.abilist | 5 ++
sysdeps/unix/sysv/linux/bits/termios-baud.h | 65 +++++++++++--------
sysdeps/unix/sysv/linux/bits/termios-c_cflag.h | 4 +-
sysdeps/unix/sysv/linux/bits/termios-cbaud.h | 47 ++++++++++++++
sysdeps/unix/sysv/linux/bits/termios.h | 50 +++++++++------
sysdeps/unix/sysv/linux/cfsetspeed.c | 58 +++++++++++++++++
sysdeps/unix/sysv/linux/csky/libc.abilist | 5 ++
sysdeps/unix/sysv/linux/hppa/libc.abilist | 5 ++
sysdeps/unix/sysv/linux/i386/libc.abilist | 5 ++
sysdeps/unix/sysv/linux/isatty.c | 29 +++++++++
sysdeps/unix/sysv/linux/isatty_nostatus.c | 9 +--
sysdeps/unix/sysv/linux/kernel-features.h | 4 ++
sysdeps/unix/sysv/linux/loongarch/lp64/libc.abilist | 5 ++
sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist | 5 ++
sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist | 5 ++
sysdeps/unix/sysv/linux/microblaze/be/libc.abilist | 5 ++
sysdeps/unix/sysv/linux/microblaze/le/libc.abilist | 5 ++
sysdeps/unix/sysv/linux/mips/Versions | 4 ++
sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist | 7 ++
sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist | 7 ++
sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist | 7 ++
sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist | 7 ++
sysdeps/unix/sysv/linux/{kernel_termios.h => mips/termios_arch.h} | 39 ++++++-----
sysdeps/unix/sysv/linux/old_termios.h | 23 +++++++
sysdeps/unix/sysv/linux/or1k/libc.abilist | 5 ++
sysdeps/unix/sysv/linux/powerpc/bits/termios-c_cflag.h | 4 +-
sysdeps/unix/sysv/linux/powerpc/bits/{termios-baud.h => termios-cbaud.h} | 42 ++++++------
sysdeps/unix/sysv/linux/powerpc/kernel_termios.h | 53 ---------------
sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist | 5 ++
sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist | 5 ++
sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist | 5 ++
sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist | 5 ++
sysdeps/unix/sysv/linux/{sparc/bits/termios-struct.h => powerpc/termios_arch.h} | 26 +++-----
sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist | 5 ++
sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist | 5 ++
sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist | 5 ++
sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist | 5 ++
sysdeps/unix/sysv/linux/sh/be/libc.abilist | 5 ++
sysdeps/unix/sysv/linux/sh/le/libc.abilist | 5 ++
sysdeps/unix/sysv/linux/sparc/Versions | 4 ++
sysdeps/unix/sysv/linux/sparc/bits/{termios-baud.h => termios-cbaud.h} | 39 ++++++-----
sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist | 7 ++
sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist | 7 ++
sysdeps/unix/sysv/linux/sparc/{kernel_termios.h => termios_arch.h} | 42 ++++++------
sysdeps/unix/sysv/linux/speed.c | 359 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------------
sysdeps/unix/sysv/linux/tcgetattr.c | 86 +++++++++++--------------
sysdeps/unix/sysv/linux/tcsetattr.c | 123 +++++++++++++++++++++--------------
sysdeps/unix/sysv/linux/{mips/kernel_termios.h => termios_arch.h} | 28 ++------
sysdeps/unix/sysv/linux/termios_internals.h | 143 +++++++++++++++++++++++++++++++++++++++++
sysdeps/unix/sysv/linux/x86_64/64/libc.abilist | 5 ++
sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist | 5 ++
62 files changed, 1133 insertions(+), 456 deletions(-)
rename sysdeps/unix/sysv/linux/alpha/bits/{termios-baud.h => termios-cbaud.h} (58%)
delete mode 100644 sysdeps/unix/sysv/linux/alpha/kernel_termios.h
rename sysdeps/unix/sysv/linux/{mips/bits/termios-struct.h => alpha/termios_arch.h} (51%)
create mode 100644 sysdeps/unix/sysv/linux/bits/termios-cbaud.h
create mode 100644 sysdeps/unix/sysv/linux/cfsetspeed.c
create mode 100644 sysdeps/unix/sysv/linux/isatty.c
rename sysdeps/unix/sysv/linux/{kernel_termios.h => mips/termios_arch.h} (54%)
create mode 100644 sysdeps/unix/sysv/linux/old_termios.h
rename sysdeps/unix/sysv/linux/powerpc/bits/{termios-baud.h => termios-cbaud.h} (58%)
delete mode 100644 sysdeps/unix/sysv/linux/powerpc/kernel_termios.h
rename sysdeps/unix/sysv/linux/{sparc/bits/termios-struct.h => powerpc/termios_arch.h} (51%)
rename sysdeps/unix/sysv/linux/sparc/bits/{termios-baud.h => termios-cbaud.h} (57%)
rename sysdeps/unix/sysv/linux/sparc/{kernel_termios.h => termios_arch.h} (51%)
rename sysdeps/unix/sysv/linux/{mips/kernel_termios.h => termios_arch.h} (50%)
create mode 100644 sysdeps/unix/sysv/linux/termios_internals.h$ git bisect log
git bisect start
# status: waiting for both good and bad commits
# bad: [d7274d718e6f3655eabe311d4eb70fabb5ffa7ef] malloc: Fix checking for small negative values of tcache_key
git bisect bad d7274d718e6f3655eabe311d4eb70fabb5ffa7ef
# good: [5cb575ca9a3da045bc3e2f0dda81ad5804bde1e6] elf: tst-audit10: split AVX512F code into dedicated functions [BZ #32882]
git bisect good 5cb575ca9a3da045bc3e2f0dda81ad5804bde1e6
# good: [74f59e9271cbb4071671e5a474e7d4f1622b186f] Create ChangeLog.old/ChangeLog.30
git bisect good 74f59e9271cbb4071671e5a474e7d4f1622b186f
# good: [5d101745814b9c1d59fb830bb044f702437f3002] malloc: Inline tcache_try_malloc
git bisect good 5d101745814b9c1d59fb830bb044f702437f3002
# good: [5f54d8bc48983bed844c02e1fe614ad223e78838] linux/termios/powerpc: deal with powerpc-unique ioctl emulation
git bisect good 5f54d8bc48983bed844c02e1fe614ad223e78838
# bad: [c559a6190e397b315fdd98d9369f15d2914d8248] elf: Remove now pointless empty ld.so.conf files in single tests
git bisect bad c559a6190e397b315fdd98d9369f15d2914d8248
# bad: [14ca258cc566fd15fa4251baa45abd873fa8b230] benchtests: Add IPv6 inet_ntop benchmark
git bisect bad 14ca258cc566fd15fa4251baa45abd873fa8b230
# bad: [8788bd77d68c6429c7f2dcbd22765525555c3cd8] sparc: Fix sparc32 Fix argument passing to __libc_start_main (BZ 32981)
git bisect bad 8788bd77d68c6429c7f2dcbd22765525555c3cd8
# bad: [c66801f36135a7b031ca37e25a35e98255b20def] include/array_length.h: add array_foreach[_const] macros
git bisect bad c66801f36135a7b031ca37e25a35e98255b20def
# bad: [bbbaf50b2a340d6913b8ad8a840dd2d66874c62b] hurd+generic/termios: make speed_t an unsigned int
git bisect bad bbbaf50b2a340d6913b8ad8a840dd2d66874c62b
# bad: [bff11c2fa945814101c08c66f8c55212ae788075] hurd/termios: remove USE_OLD_TTY
git bisect bad bff11c2fa945814101c08c66f8c55212ae788075
# bad: [5cf101a85aae0d703cdd8ed7b25fe288e41fdacb] linux: implement arbitrary and split speeds in termios
git bisect bad 5cf101a85aae0d703cdd8ed7b25fe288e41fdacb
# first bad commit: [5cf101a85aae0d703cdd8ed7b25fe288e41fdacb] linux: implement arbitrary and split speeds in termiosThe issue needs to be reported on the sourceware bugzilla which handles glibc bugs. seth libc for the component? https://sourceware.org/bugzilla/describ … duct=glibc
Offline
Interesting. Thanks for the bisection! It appears that RepetierHost [1] is a Windows binary which is run via Mono.. and I wonder if that's part of the story here? See also this post [2] (also from OP?) for some additional background. I don't have the hardware to try and repro. I tried in a VM but virtual serial ports in QEMU don't seem to allow 250000 anyway.
I can open an upstream Glibc Bugzilla but wanted to flag the possibility of raising it with the Repetier first? Or has the OP tried recompiling SetBaudrate.cpp against latest Glibc? (yes, I know, a longshot!)
[1] https://aur.archlinux.org/packages/repetier-host
[2] https://forum.repetier.com/discussion/8 … 50000-baud
Offline
No, I repeated the same issue with stty.
RepetierHost calls a Linux binary named SetBaudrate.
Last edited by JanErik (2025-08-29 18:27:00)
Offline
RepetierHost calls a Linux binary named SetBaudrate.
Of course, but it appears you have missed my point. SetBaudrate is compiled from source in the AUR PKGBUILD [1]. Have you recompiled SetBaudrate against glibc-2.42x?
Offline
@JanErik, stty hasn't been rebuilt against the latest glibc either, if this is because of the ABI extension of the isolated patch, it would be affected as well and it's gonna be easier to recompile SetBaudrate than the coreutils (which in turn would be necessary)
Offline
My RepetierHost is not from AUR, and seems AUR is down right now, but I recompiled SetBaudrate (after updating glibc and all other packages and rebooting) as the configureFirst.sh script does, simply "g++ SetBaudrate.cpp -o SetBaudrate".
Still behaves the same.
Offline
Offline
As requested in the upstream report, could you please run:
strace -ff -o output.txt <program>This should produce a bunch of output.txt.* files which can then be uploaded somewhere...
Offline
Files here: https://jeskata.kapsi.fi/repetierhost_strace/ .
Last edited by JanErik (2025-08-30 10:42:25)
Offline
Thanks for the files. As per comments in the upstream report, "coreutils-git" includes changes to "stty" to accommodate latest Glibc refactoring. As a workaround, it might be possible for you to compile "coreutils-git" (but don't install it) and just grab the "stty" binary and use it as a replacement for "SetBaudrate" via a wrapper script. Any chance you can give that a test?
Offline
If it helps I built the latest coreutils from git coreutils-263+rg735a4a27f3d3-1-x86_64.pkg.tar.zst to repeat Toolybird's warning only extract and use stty from the package, do not install it.
Offline
Tried building coreutils-git, got
CCLD src/[
CCLD src/b2sum
CCLD src/base64
CCLD src/base32
lib/careadlinkat.c: In function 'careadlinkat.constprop':
lib/careadlinkat.c:180:10: error: function may return address of local variable [-Werror=return-local-addr]
180 | return readlink_stk (fd, filename, buffer, buffer_size, alloc,
| ^
lib/careadlinkat.c:179:8: note: declared here
179 | char stack_buf[STACK_BUF_SIZE];
| ^
lto1: all warnings being treated as errors
make[3]: *** [/tmp/ccz5pik1.mk:2: /tmp/cc5qSSbb.ltrans0.ltrans.o] Error 1
lto-wrapper: fatal error: make returned 2 exit status
compilation terminated.
/usr/bin/ld: error: lto-wrapper failed
collect2: error: ld returned 1 exit status
make[2]: *** [Makefile:12158: src/stdbuf] Error 1
make[2]: *** Waiting for unfinished jobs....
make[2]: Leaving directory '/home/jskata/coreutils-git/src/coreutils'
make[1]: *** [Makefile:23601: all-recursive] Error 1
make[1]: Leaving directory '/home/jskata/coreutils-git/src/coreutils'
make: *** [Makefile:9414: all] Error 2
==> ERROR: A failure occurred in build().
Aborting...Offline
In the PKGBUILD change
--enable-no-install-program="groups,hostname,kill,uptime"to
--enable-no-install-program="groups,hostname,kill,uptime" \
--enable-gcc-warnings=noOffline
Or as suggested in the bug:
// Set serial port to any baudrate if possible
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <time.h>
#include <string.h>
#include <sys/ioctl.h>
#include <termios.h>
#include <linux/serial.h>
#include <iostream>
#include <stdlib.h>
using namespace std;
int open_port(const char *port)
{
int fd = open(port, O_RDWR | O_NOCTTY | O_NDELAY);
if(fd == -1) {
printf("error: Unable to open %s. \n",port);
exit(-2);
}
else
{
fcntl(fd, F_SETFL, 0);
}
return(fd);
} //open_port
#define rate_to_constant(x) (x)
void set_baudrate(int handle, int baud) {
termios ios;
int speed = rate_to_constant(baud);
if(speed == 0) {
struct serial_struct ss;
ss.reserved_char[0] = 0;
if(ioctl(handle, TIOCGSERIAL, &ss) < 0) {
cerr << "error: TIOCGSERIAL" << endl;
exit(-2);
}
ss.flags = (ss.flags & ~ASYNC_SPD_MASK) | ASYNC_SPD_CUST;
ss.custom_divisor = (ss.baud_base + (baud / 2)) / baud;
ss.custom_divisor = (ss.baud_base + (baud / 2)) / baud;
if(ss.custom_divisor == 0) {
cerr << "error: baud_base (" << ss.baud_base << ") does not allow setting custom baud rate" << endl;
exit(-2);
}
long closestSpeed = ss.baud_base / ss.custom_divisor;
// cout << " Closest speed " << closestSpeed << endl;
ss.reserved_char[0] = 0;
if (closestSpeed < baud * 98 / 100 || closestSpeed > baud * 102 / 100) {
cerr << "error: couldn't set desired baud rate " << baud << endl;
exit(-2);
}
if(ioctl(handle, TIOCSSERIAL, &ss) < 0) {
cerr << "error: Setting baudrate " << baud << " failed" << endl;
exit(-2);
}
}
fcntl(handle, F_SETFL, 0);
tcgetattr(handle, &ios);
::cfsetispeed(&ios, speed ? speed : 38400);
::cfsetospeed(&ios, speed ? speed : 38400);
cfmakeraw(&ios);
ios.c_cflag |= (CLOCAL | CREAD);
ios.c_cflag &= ~CRTSCTS;
if (tcsetattr(handle, TCSANOW, &ios) != 0) {
cerr << "error: tcsetattr failed" << endl;
exit(-2);
}
}
int main(int argc, const char* argv[])
{
if(argc != 3) {
cerr << "Syntax: SetBaudrate serialDevice baudrate" << endl;
exit(-1);
}
int fd = open_port(argv[1]);
if(fd<0) {
cerr << "error: could not open device " << argv[1] << endl;
exit(-2);
}
int baud = atoi(argv[2]);
if(baud<=0) {
cerr << "error: Positive baud rate needed, but I got " << argv[2] << endl;
exit(-2);
}
set_baudrate(fd, baud);
return(0);
}g++ -o SetBaudrate SetBaudrate.cppAs per comments in the upstream report, "coreutils-git" includes changes to "stty" to accommodate latest Glibc refactoring.
This should give everybody pause - "refactoring" that requires downstream patches to restore proper function isn't "refactoring" but an API break that requires an explicit release note.
Offline
I compiled coreutils-git now and made a SetBaudrate script to call stty, but when calling it from RepetierHost I get
Forcing set baudrate failedIf I call the script manually it seems to go through without complaints, also I can call stty directly to set 250000 which didn't work before.
$ cat RepetierHost/SetBaudrate
/home/jskata/RepetierHost/stty -F /dev/ttyACM0 250000Though the update SetBaudrate.cpp works.
Last edited by JanErik (2025-09-01 18:36:22)
Offline
See the script here: https://sourceware.org/bugzilla/show_bu … =33340#c12 but oc. you can also just use the updated SetBaudrate binary.
Offline
It seems I am getting hit by this bug as well but in a program that uses the libserialport library. I posted my question to this forum here on this forum and added to the bugzilla entry here.
Offline
@Toolybird do you think https://github.com/nix-rust/nix/issues/2672 which broke uutils-coreutils is the same issue and if so will you raise it with upstream glibc? There is also now the proposed compatibility fix series [PATCH v2 1/3] linux/termios: clear k_termios.c_cflag & CIBAUD for non-split speed [BZ 33340].
Offline
@toolybird You may have seen that hpax created a fork for libserialport that modernizes that code to work with current glibc v2.42. Do you think Arch should package that fork instead of mainline for libserialport?
Offline
@Dekay can you please try the glibc-2.42 branch of my fork of the libserialport PKGBUILD that has hpax's patches applied? I have also created a termios-compat branch of my fork of the glibc PKGBUILD. Which might fix your issue without needing to patch libserialport. Although there is little change the glibc package maintainers will agree to take the patches before they are accepted upstream and backported to the release/2.42/master branch.
Offline
@Dekay can you please try the glibc-2.42 branch of my fork of the libserialport PKGBUILD that has hpax's patches applied? I have also created a termios-compat branch of my fork of the glibc PKGBUILD. Which might fix your issue without needing to patch libserialport. Although there is little change the glibc package maintainers will agree to take the patches before they are accepted upstream and backported to the release/2.42/master branch.
@loqs : I'm very sorry I didn't respond. I didn't mean to ignore you... I just didn't see a notification for this message in my email.
In the interim, I've been running with hpax's fork of libserialport and it works perfectly. I could give your termios-compat branch a try as well if you still need that. Can you confirm that trying that doesn't create a risk of serious breakage? I'm always nervous messing with a package this fundamental.
Offline
@Dekay as the glibc patches have not been merged upstream, I can not see a point in testing termios-compat.
@Toolybird do you think it is worth opening merge requests for libserialport?
Last edited by loqs (2025-10-22 23:32:17)
Offline
@loqs FYI, it looks like there is a V3 set of patches now that might help improve glibc compat with existing applications
Offline