Incorrect terminal baud rate on glibc 2.42+
- Dominant language
- Haskell
- Stars
- 124
- Forks
- 99
- PR merge metrics
- No merged PRs in 30d
Description
BaudRate pattern synonyms (B9600 etc.) are baked in by hsc2hs at GHC build time and become wrong when the runtime glibc differs from the build-time glibc, because glibc 2.42 changed B9600 from 13 to 9600.
### Your environment
Which OS do you use:
Ubuntu 25.10 (glibc 2.42), GHC 9.6.7 (built against glibc <= 2.41), unix-2.8.6.0
Describe your project (alternative: link to the project):
Programming a small TTY USB device (serial port at 9600 baud)
### Steps to reproduce
Use `withOutputSpeed attrs B9600` to configure a serial port. The `B9600` pattern synonym resolves to `BaudRate 13` (the old glibc kernel-encoding constant baked in at GHC build time), but the runtime glibc 2.42 `cfsetospeed` expects 9600. It interprets 13 as a custom baud rate via `BOTHER`, configuring the port for 13 baud.
### Expected behaviour
`B9600` should set the serial port to 9600 baud. `cfsetospeed` should receive a value that the runtime glibc interprets as 9600 baud.
### Actual behaviour
The port is configured for 13 baud. The device does not respond. Visible via `strace`: `ioctl(TCSETS2, {c_cflag=BOTHER, c_ospeed=13})` instead of `c_cflag=B9600, c_ospeed=9600`. Workaround: use `BaudRate 9600` instead of `B9600`.
### Include debug information
The `BaudRate` pattern synonyms are defined via `hsc2hs` `#const` (e.g. `pattern B9600 = BaudRate (#const B9600)`), capturing glibc's `B9600` macro at GHC build time. In glibc <= 2.41, `B9600 = 13` (kernel encoding). In glibc >= 2.42, `B9600 = 9600` ("sane speed_t"). When GHC is built against old glibc but runs on new glibc, the stale constant 13 is passed to the new versioned `cfsetospeed@GLIBC_2.42`, which treats it as an arbitrary speed.
glibc change: commit [5cf101a85aae](https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=5cf101a85aae0d703cdd8ed7b25fe288e41fdacb) and [relevant changeset](https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=b65e6270fac585b85e18dcd6538ca904d3ed7868). Same bug in Rust: [rust-lang/libc#4692](https://github.com/rust-lang/libc/issues/4692).
### API breaking changes
The `BaudRate` pattern synonyms are now potentially wrong on any system where the build-time and runtime glibc versions straddle the 2.41/2.42 boundary.
### Posix compliance
POSIX specifies `speed_t` as opaque and the `Bxxx` constants as implementation-defined. The issue is that glibc changed their values, but the `unix` package bakes them in at compile time rather than querying them at runtime.
Contributor guide
No contributing guide indexed for this repository
Assessment
This issue has not been assessed yet.