PS here are the two test programs I wrote while preparing the bug report.
#include <termios.h> #include <stdio.h> #include <stdlib.h>
#define BOTHER 0010000 int main(int argc, const char **argv) { struct termios to; int r; r = tcgetattr(0, &to); if (r) { perror("tcgetattr"); exit(-1); } const char *arg = argv[1]; if (!arg) { printf("cfgetispeed=%lu cfgetospeed=%lu", (unsigned long)cfgetispeed(&to), (unsigned long)cfgetospeed(&to)); if ((to.c_cflag & CBAUD) == BOTHER) printf(" BOTHER c_ispeed=%lu c_ospeed=%lu", (unsigned long)to.c_ispeed, (unsigned long)to.c_ospeed); putchar('\n'); exit(0); } speed_t spd = atoi(arg); r = cfsetspeed(&to, spd); if (r) { perror("tcsetspeed failed (will do by hand)"); to.c_ispeed = to.c_ospeed = spd; to.c_cflag &= ~CBAUD; to.c_cflag |= BOTHER; } r = tcsetattr(0, TCSANOW, &to); if (r) { perror("tcsetattr"); exit(-1); } return 0; }
#include <stdio.h> #include <stdlib.h> #include <sys/ioctl.h> #include "/usr/include/asm-generic/termbits.h" #include "/usr/include/asm-generic/ioctls.h" #define BOTHER 0010000 int main(int argc, const char **argv) { struct termios2 to; int r; r = ioctl(0, TCGETS2, &to); if (r) { perror("TCGETS2"); exit(-1); } const char *arg = argv[1]; if (!arg) { printf("c_cflag&CBAUD=0%lo", (unsigned long)(to.c_cflag&CBAUD)); if ((to.c_cflag & CBAUD) == BOTHER) printf(" BOTHER c_ispeed=%lu c_ospeed=%lu", (unsigned long)to.c_ispeed, (unsigned long)to.c_ospeed); putchar('\n'); exit(0); } speed_t spd = atoi(arg); to.c_ispeed = to.c_ospeed = spd; to.c_cflag &= ~CBAUD; to.c_cflag |= BOTHER; r = ioctl(0, TCSETS2, &to); if (r) { perror("TCSETS2"); exit(-1); } return 0; }