diff --git a/NEWS b/NEWS index afe8076dfc..cc668344c1 100644 --- a/NEWS +++ b/NEWS @@ -22,6 +22,10 @@ Major new features: * The ISO C2Y family of unsigned abs functions, i.e. uabs, ulabs, ullabs and uimaxabs, are now supported. +* On Linux, the interface now supports arbitrary baud rates; + speed_t is redefined to simply be the baud rate specified as an + unsigned int, which matches the kernel interface. + Deprecated and removed features, and other changes affecting compatibility: * The glibc.rtld.execstack now supports a compatibility mode to allow diff --git a/sysdeps/unix/sysv/linux/Versions b/sysdeps/unix/sysv/linux/Versions index 55d565545a..b721331bf7 100644 --- a/sysdeps/unix/sysv/linux/Versions +++ b/sysdeps/unix/sysv/linux/Versions @@ -332,6 +332,13 @@ libc { sched_getattr; sched_setattr; } + GLIBC_2.42 { + cfgetospeed; + cfgetispeed; + cfsetospeed; + cfsetispeed; + cfsetspeed; + } GLIBC_PRIVATE { # functions used in other libraries __syscall_rt_sigqueueinfo; diff --git a/sysdeps/unix/sysv/linux/aarch64/libc.abilist b/sysdeps/unix/sysv/linux/aarch64/libc.abilist index aa6bf483dd..fdccf84d8f 100644 --- a/sysdeps/unix/sysv/linux/aarch64/libc.abilist +++ b/sysdeps/unix/sysv/linux/aarch64/libc.abilist @@ -2752,6 +2752,11 @@ GLIBC_2.41 sched_getattr F GLIBC_2.41 sched_setattr F GLIBC_2.42 __inet_ntop_chk F GLIBC_2.42 __inet_pton_chk F +GLIBC_2.42 cfgetispeed F +GLIBC_2.42 cfgetospeed F +GLIBC_2.42 cfsetispeed F +GLIBC_2.42 cfsetospeed F +GLIBC_2.42 cfsetspeed F GLIBC_2.42 pthread_gettid_np F GLIBC_2.42 uabs F GLIBC_2.42 uimaxabs F diff --git a/sysdeps/unix/sysv/linux/alpha/bits/termios-c_cflag.h b/sysdeps/unix/sysv/linux/alpha/bits/termios-c_cflag.h index 1f9f7f2680..d8308848c6 100644 --- a/sysdeps/unix/sysv/linux/alpha/bits/termios-c_cflag.h +++ b/sysdeps/unix/sysv/linux/alpha/bits/termios-c_cflag.h @@ -36,4 +36,6 @@ #ifdef __USE_MISC # define ADDRB 04000000000 +# define CMSPAR 010000000000 /* Mark or space (stick) parity. */ +# define CRTSCTS 020000000000 /* Flow control. */ #endif diff --git a/sysdeps/unix/sysv/linux/alpha/bits/termios-baud.h b/sysdeps/unix/sysv/linux/alpha/bits/termios-cbaud.h similarity index 58% rename from sysdeps/unix/sysv/linux/alpha/bits/termios-baud.h rename to sysdeps/unix/sysv/linux/alpha/bits/termios-cbaud.h index 324d5d8776..69421f6797 100644 --- a/sysdeps/unix/sysv/linux/alpha/bits/termios-baud.h +++ b/sysdeps/unix/sysv/linux/alpha/bits/termios-cbaud.h @@ -17,30 +17,29 @@ . */ #ifndef _TERMIOS_H -# error "Never include directly; use instead." +# error "Never include directly; use instead." #endif #ifdef __USE_MISC -# define CBAUD 0000037 -# define CBAUDEX 0000000 -# define CMSPAR 010000000000 /* mark or space (stick) parity */ -# define CRTSCTS 020000000000 /* flow control */ +# define CBAUD 000000037 +# define CBAUDEX 000000000 +# define CIBAUD 007600000 +# define IBSHIFT 16 #endif -#define B57600 00020 -#define B115200 00021 -#define B230400 00022 -#define B460800 00023 -#define B500000 00024 -#define B576000 00025 -#define B921600 00026 -#define B1000000 00027 -#define B1152000 00030 -#define B1500000 00031 -#define B2000000 00032 -#define B2500000 00033 -#define B3000000 00034 -#define B3500000 00035 -#define B4000000 00036 - -#define __MAX_BAUD B4000000 +#define __B57600 00020 +#define __B115200 00021 +#define __B230400 00022 +#define __B460800 00023 +#define __B500000 00024 +#define __B576000 00025 +#define __B921600 00026 +#define __B1000000 00027 +#define __B1152000 00030 +#define __B1500000 00031 +#define __B2000000 00032 +#define __B2500000 00033 +#define __B3000000 00034 +#define __B3500000 00035 +#define __B4000000 00036 +#define __BOTHER 00037 diff --git a/sysdeps/unix/sysv/linux/alpha/kernel-features.h b/sysdeps/unix/sysv/linux/alpha/kernel-features.h index 6eae48f13e..83fdf91222 100644 --- a/sysdeps/unix/sysv/linux/alpha/kernel-features.h +++ b/sysdeps/unix/sysv/linux/alpha/kernel-features.h @@ -54,4 +54,15 @@ #undef __ASSUME_CLONE3 #define __ASSUME_CLONE3 0 +/* Alpha did not provide BOTHER, CIBAUD or the termios2 ioctls until + kernel 4.20. Even though struct __kernel_termios and struct + termios2 are the same on Alpha, Calling the legacy TCSETS* ioctls + with BOTHER set triggers a bug in these old kernels, so only use + the legacy TCSETS* ioctl numbers if neither BOTHER nor split speed is + needed; that way the code will fail gracefully. */ +#if __LINUX_KERNEL_VERSION < 0x041400 +# undef __ASSUME_TERMIOS2 +# define __ASSUME_TERMIOS2 0 +#endif + #endif /* _KERNEL_FEATURES_H */ diff --git a/sysdeps/unix/sysv/linux/alpha/kernel_termios.h b/sysdeps/unix/sysv/linux/alpha/kernel_termios.h deleted file mode 100644 index 6a777ddb6e..0000000000 --- a/sysdeps/unix/sysv/linux/alpha/kernel_termios.h +++ /dev/null @@ -1,43 +0,0 @@ -/* Copyright (C) 1997-2025 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library. If not, see - . */ - -#ifndef _KERNEL_TERMIOS_H -#define _KERNEL_TERMIOS_H 1 - -/* The following corresponds to the values from the Linux 2.1.20 kernel. */ - -/* We need the definition of tcflag_t, cc_t, and speed_t. */ -#include - -#define __KERNEL_NCCS 19 - -struct __kernel_termios - { - tcflag_t c_iflag; /* input mode flags */ - tcflag_t c_oflag; /* output mode flags */ - tcflag_t c_cflag; /* control mode flags */ - tcflag_t c_lflag; /* local mode flags */ - cc_t c_cc[__KERNEL_NCCS]; /* control characters */ - cc_t c_line; /* line discipline */ - speed_t c_ispeed; /* input speed */ - speed_t c_ospeed; /* output speed */ - }; - -#define _HAVE_C_ISPEED 1 -#define _HAVE_C_OSPEED 1 - -#endif /* kernel_termios.h */ diff --git a/sysdeps/unix/sysv/linux/alpha/libc.abilist b/sysdeps/unix/sysv/linux/alpha/libc.abilist index d5df9656a8..1e3f278155 100644 --- a/sysdeps/unix/sysv/linux/alpha/libc.abilist +++ b/sysdeps/unix/sysv/linux/alpha/libc.abilist @@ -3099,6 +3099,11 @@ GLIBC_2.41 sched_getattr F GLIBC_2.41 sched_setattr F GLIBC_2.42 __inet_ntop_chk F GLIBC_2.42 __inet_pton_chk F +GLIBC_2.42 cfgetispeed F +GLIBC_2.42 cfgetospeed F +GLIBC_2.42 cfsetispeed F +GLIBC_2.42 cfsetospeed F +GLIBC_2.42 cfsetspeed F GLIBC_2.42 pthread_gettid_np F GLIBC_2.42 uabs F GLIBC_2.42 uimaxabs F diff --git a/sysdeps/unix/sysv/linux/mips/bits/termios-struct.h b/sysdeps/unix/sysv/linux/alpha/termios_arch.h similarity index 51% rename from sysdeps/unix/sysv/linux/mips/bits/termios-struct.h rename to sysdeps/unix/sysv/linux/alpha/termios_arch.h index ef698218f3..20025f2549 100644 --- a/sysdeps/unix/sysv/linux/mips/bits/termios-struct.h +++ b/sysdeps/unix/sysv/linux/alpha/termios_arch.h @@ -1,5 +1,6 @@ -/* struct termios definition. Linux/mips version. - Copyright (C) 2019-2025 Free Software Foundation, Inc. +/* Architectural parameters for Linux termios - Alpha/PowerPC version + + Copyright (C) 1997-2025 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -13,22 +14,13 @@ Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library. If not, see + License along with the GNU C Library; if not, see . */ -#ifndef _TERMIOS_H -# error "Never include directly; use instead." +#ifndef TERMIOS_INTERNALS_H +# error " should only be included from " #endif -#define NCCS 32 -struct termios - { - tcflag_t c_iflag; /* input mode flags */ - tcflag_t c_oflag; /* output mode flags */ - tcflag_t c_cflag; /* control mode flags */ - tcflag_t c_lflag; /* local mode flags */ - cc_t c_line; /* line discipline */ - cc_t c_cc[NCCS]; /* control characters */ -#define _HAVE_STRUCT_TERMIOS_C_ISPEED 0 -#define _HAVE_STRUCT_TERMIOS_C_OSPEED 0 - }; +#define _TERMIOS2_NCCS 19 +#define _HAVE_TERMIOS2_C_CC_BEFORE_C_LINE 1 +#define _HAVE_STRUCT_OLD_TERMIOS 0 diff --git a/sysdeps/unix/sysv/linux/arc/libc.abilist b/sysdeps/unix/sysv/linux/arc/libc.abilist index c46c08da85..7b7717d1d1 100644 --- a/sysdeps/unix/sysv/linux/arc/libc.abilist +++ b/sysdeps/unix/sysv/linux/arc/libc.abilist @@ -2513,6 +2513,11 @@ GLIBC_2.41 sched_getattr F GLIBC_2.41 sched_setattr F GLIBC_2.42 __inet_ntop_chk F GLIBC_2.42 __inet_pton_chk F +GLIBC_2.42 cfgetispeed F +GLIBC_2.42 cfgetospeed F +GLIBC_2.42 cfsetispeed F +GLIBC_2.42 cfsetospeed F +GLIBC_2.42 cfsetspeed F GLIBC_2.42 pthread_gettid_np F GLIBC_2.42 uabs F GLIBC_2.42 uimaxabs F diff --git a/sysdeps/unix/sysv/linux/arm/be/libc.abilist b/sysdeps/unix/sysv/linux/arm/be/libc.abilist index 4df150c0f0..f64bf3f327 100644 --- a/sysdeps/unix/sysv/linux/arm/be/libc.abilist +++ b/sysdeps/unix/sysv/linux/arm/be/libc.abilist @@ -2805,6 +2805,11 @@ GLIBC_2.41 sched_getattr F GLIBC_2.41 sched_setattr F GLIBC_2.42 __inet_ntop_chk F GLIBC_2.42 __inet_pton_chk F +GLIBC_2.42 cfgetispeed F +GLIBC_2.42 cfgetospeed F +GLIBC_2.42 cfsetispeed F +GLIBC_2.42 cfsetospeed F +GLIBC_2.42 cfsetspeed F GLIBC_2.42 pthread_gettid_np F GLIBC_2.42 uabs F GLIBC_2.42 uimaxabs F diff --git a/sysdeps/unix/sysv/linux/arm/le/libc.abilist b/sysdeps/unix/sysv/linux/arm/le/libc.abilist index be294783f6..c065fe80fc 100644 --- a/sysdeps/unix/sysv/linux/arm/le/libc.abilist +++ b/sysdeps/unix/sysv/linux/arm/le/libc.abilist @@ -2802,6 +2802,11 @@ GLIBC_2.41 sched_getattr F GLIBC_2.41 sched_setattr F GLIBC_2.42 __inet_ntop_chk F GLIBC_2.42 __inet_pton_chk F +GLIBC_2.42 cfgetispeed F +GLIBC_2.42 cfgetospeed F +GLIBC_2.42 cfsetispeed F +GLIBC_2.42 cfsetospeed F +GLIBC_2.42 cfsetspeed F GLIBC_2.42 pthread_gettid_np F GLIBC_2.42 uabs F GLIBC_2.42 uimaxabs F diff --git a/sysdeps/unix/sysv/linux/bits/termios-baud.h b/sysdeps/unix/sysv/linux/bits/termios-baud.h index e63a3eb418..1e41338b57 100644 --- a/sysdeps/unix/sysv/linux/bits/termios-baud.h +++ b/sysdeps/unix/sysv/linux/bits/termios-baud.h @@ -20,29 +20,44 @@ # error "Never include directly; use instead." #endif -#ifdef __USE_MISC -# define CBAUD 000000010017 /* Baud speed mask (not in POSIX). */ -# define CBAUDEX 000000010000 /* Extra baud speed mask, included in CBAUD. - (not in POSIX). */ -# define CIBAUD 002003600000 /* Input baud rate (not used). */ -# define CMSPAR 010000000000 /* Mark or space (stick) parity. */ -# define CRTSCTS 020000000000 /* Flow control. */ -#endif +#define B0 0U +#define B50 50U +#define B75 75U +#define B110 110U +#define B134 134U +#define B150 150U +#define B200 200U +#define B300 300U +#define B600 600U +#define B1200 1200U +#define B1800 1800U +#define B2400 2400U +#define B4800 4800U +#define B7200 7200U +#define B9600 9600U +#define B14400 14400U +#define B19200 19200U +#define B28800 28800U +#define B33600 33600U +#define B38400 38400U +#define B57600 57600U +#define B76800 76800U +#define B115200 115200U +#define B153600 153600U +#define B230400 230400U +#define B307200 307200U +#define B460800 460800U +#define B500000 500000U +#define B576000 576000U +#define B614400 614400U +#define B921600 921600U +#define B1000000 1000000U +#define B1152000 1152000U +#define B1500000 1500000U +#define B2000000 2000000U +#define B2500000 2500000U +#define B3000000 3000000U +#define B3500000 3500000U +#define B4000000 4000000U -/* Extra output baud rates (not in POSIX). */ -#define B57600 0010001 -#define B115200 0010002 -#define B230400 0010003 -#define B460800 0010004 -#define B500000 0010005 -#define B576000 0010006 -#define B921600 0010007 -#define B1000000 0010010 -#define B1152000 0010011 -#define B1500000 0010012 -#define B2000000 0010013 -#define B2500000 0010014 -#define B3000000 0010015 -#define B3500000 0010016 -#define B4000000 0010017 -#define __MAX_BAUD B4000000 +#define __MAX_BAUD 4294967295U diff --git a/sysdeps/unix/sysv/linux/bits/termios-c_cflag.h b/sysdeps/unix/sysv/linux/bits/termios-c_cflag.h index bbbb621d4e..befd25a758 100644 --- a/sysdeps/unix/sysv/linux/bits/termios-c_cflag.h +++ b/sysdeps/unix/sysv/linux/bits/termios-c_cflag.h @@ -34,5 +34,7 @@ #define CLOCAL 0004000 #ifdef __USE_MISC -# define ADDRB 04000000000 +# define ADDRB 04000000000 +# define CMSPAR 010000000000 /* Mark or space (stick) parity. */ +# define CRTSCTS 020000000000 /* Flow control. */ #endif diff --git a/sysdeps/unix/sysv/linux/bits/termios-cbaud.h b/sysdeps/unix/sysv/linux/bits/termios-cbaud.h new file mode 100644 index 0000000000..b9aadff8db --- /dev/null +++ b/sysdeps/unix/sysv/linux/bits/termios-cbaud.h @@ -0,0 +1,47 @@ +/* termios baud rate selection definitions. Linux/generic version. + Copyright (C) 2019-2025 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library. If not, see + . */ + +#ifndef _TERMIOS_H +# error "Never include directly; use instead." +#endif + +#ifdef __USE_MISC +# define CBAUD 000000010017 /* Baud speed mask (not in POSIX). */ +# define CBAUDEX 000000010000 /* Extra baud speed mask, included in CBAUD. + (not in POSIX). */ +# define CIBAUD 002003600000 /* Input baud rate. */ +# define IBSHIFT 16 +#endif + +/* Extra output baud rates (not in POSIX). */ +#define __BOTHER 0010000 +#define __B57600 0010001 +#define __B115200 0010002 +#define __B230400 0010003 +#define __B460800 0010004 +#define __B500000 0010005 +#define __B576000 0010006 +#define __B921600 0010007 +#define __B1000000 0010010 +#define __B1152000 0010011 +#define __B1500000 0010012 +#define __B2000000 0010013 +#define __B2500000 0010014 +#define __B3000000 0010015 +#define __B3500000 0010016 +#define __B4000000 0010017 diff --git a/sysdeps/unix/sysv/linux/bits/termios.h b/sysdeps/unix/sysv/linux/bits/termios.h index 3bd1e22829..14de3fcb55 100644 --- a/sysdeps/unix/sysv/linux/bits/termios.h +++ b/sysdeps/unix/sysv/linux/bits/termios.h @@ -24,35 +24,41 @@ typedef unsigned char cc_t; typedef unsigned int speed_t; typedef unsigned int tcflag_t; -#include +#ifdef _TERMIOS_H +# include +#endif + #include #include #include /* c_cflag bit meaning */ -#define B0 0000000 /* hang up */ -#define B50 0000001 -#define B75 0000002 -#define B110 0000003 -#define B134 0000004 -#define B150 0000005 -#define B200 0000006 -#define B300 0000007 -#define B600 0000010 -#define B1200 0000011 -#define B1800 0000012 -#define B2400 0000013 -#define B4800 0000014 -#define B9600 0000015 -#define B19200 0000016 -#define B38400 0000017 -#ifdef __USE_MISC -# define EXTA B19200 -# define EXTB B38400 -#endif -#include - #include + +#define __B0 0000000 /* hang up */ +#define __B50 0000001 +#define __B75 0000002 +#define __B110 0000003 +#define __B134 0000004 +#define __B150 0000005 +#define __B200 0000006 +#define __B300 0000007 +#define __B600 0000010 +#define __B1200 0000011 +#define __B1800 0000012 +#define __B2400 0000013 +#define __B4800 0000014 +#define __B9600 0000015 +#define __B19200 0000016 +#define __B38400 0000017 +#include + +#ifdef __USE_MISC +# define EXTA __B19200 +# define EXTB __B38400 +# define BOTHER __BOTHER +#endif + #include #ifdef __USE_MISC @@ -74,3 +80,5 @@ typedef unsigned int tcflag_t; #include #include + +#include diff --git a/sysdeps/unix/sysv/linux/cfsetspeed.c b/sysdeps/unix/sysv/linux/cfsetspeed.c new file mode 100644 index 0000000000..8fd95875d9 --- /dev/null +++ b/sysdeps/unix/sysv/linux/cfsetspeed.c @@ -0,0 +1,58 @@ +/* cfsetspeed(), Linux version. + Copyright (C) 1991-2025 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#include + +/* Set both the input and output baud rates stored in *TERMIOS_P to SPEED. */ +int +__cfsetspeed (struct termios *termios_p, speed_t speed) +{ + tcflag_t cbaud = ___speed_to_cbaud (speed); + + termios_p->c_ospeed = speed; + termios_p->c_ispeed = speed; + termios_p->c_cflag &= ~(CBAUD | CIBAUD); + termios_p->c_cflag |= cbaud | (cbaud << IBSHIFT); + + return 0; +} +versioned_symbol (libc, __cfsetspeed, cfsetspeed, GLIBC_2_42); + +#if _TERMIOS_OLD_COMPAT + +int +attribute_compat_text_section +__old_cfsetspeed (old_termios_t *termios_p, speed_t speed) +{ + speed_t real_speed = ___cbaud_to_speed (speed, -1); + if (real_speed == (speed_t)-1) + return INLINE_SYSCALL_ERROR_RETURN_VALUE (EINVAL); + +#if !_HAVE_STRUCT_OLD_TERMIOS + /* Otherwise these fields don't exist in old_termios_t */ + termios_p->c_ospeed = real_speed; + termios_p->c_ispeed = real_speed; +#endif + termios_p->c_cflag &= ~(CBAUD | CIBAUD); + termios_p->c_cflag |= speed | (speed << IBSHIFT); + + return 0; +} +compat_symbol (libc, __old_cfsetspeed, cfsetspeed, GLIBC_2_0); + +#endif /* _TERMIOS_OLD_COMPAT */ diff --git a/sysdeps/unix/sysv/linux/csky/libc.abilist b/sysdeps/unix/sysv/linux/csky/libc.abilist index f123757134..69ba60ea09 100644 --- a/sysdeps/unix/sysv/linux/csky/libc.abilist +++ b/sysdeps/unix/sysv/linux/csky/libc.abilist @@ -2789,6 +2789,11 @@ GLIBC_2.41 sched_getattr F GLIBC_2.41 sched_setattr F GLIBC_2.42 __inet_ntop_chk F GLIBC_2.42 __inet_pton_chk F +GLIBC_2.42 cfgetispeed F +GLIBC_2.42 cfgetospeed F +GLIBC_2.42 cfsetispeed F +GLIBC_2.42 cfsetospeed F +GLIBC_2.42 cfsetspeed F GLIBC_2.42 pthread_gettid_np F GLIBC_2.42 uabs F GLIBC_2.42 uimaxabs F diff --git a/sysdeps/unix/sysv/linux/hppa/libc.abilist b/sysdeps/unix/sysv/linux/hppa/libc.abilist index 2dc85b9533..dea7c09692 100644 --- a/sysdeps/unix/sysv/linux/hppa/libc.abilist +++ b/sysdeps/unix/sysv/linux/hppa/libc.abilist @@ -2826,6 +2826,11 @@ GLIBC_2.41 sched_getattr F GLIBC_2.41 sched_setattr F GLIBC_2.42 __inet_ntop_chk F GLIBC_2.42 __inet_pton_chk F +GLIBC_2.42 cfgetispeed F +GLIBC_2.42 cfgetospeed F +GLIBC_2.42 cfsetispeed F +GLIBC_2.42 cfsetospeed F +GLIBC_2.42 cfsetspeed F GLIBC_2.42 pthread_gettid_np F GLIBC_2.42 uabs F GLIBC_2.42 uimaxabs F diff --git a/sysdeps/unix/sysv/linux/i386/libc.abilist b/sysdeps/unix/sysv/linux/i386/libc.abilist index 1e38217ec6..4c05ab1c6e 100644 --- a/sysdeps/unix/sysv/linux/i386/libc.abilist +++ b/sysdeps/unix/sysv/linux/i386/libc.abilist @@ -3009,6 +3009,11 @@ GLIBC_2.41 sched_getattr F GLIBC_2.41 sched_setattr F GLIBC_2.42 __inet_ntop_chk F GLIBC_2.42 __inet_pton_chk F +GLIBC_2.42 cfgetispeed F +GLIBC_2.42 cfgetospeed F +GLIBC_2.42 cfsetispeed F +GLIBC_2.42 cfsetospeed F +GLIBC_2.42 cfsetspeed F GLIBC_2.42 pthread_gettid_np F GLIBC_2.42 uabs F GLIBC_2.42 uimaxabs F diff --git a/sysdeps/unix/sysv/linux/isatty.c b/sysdeps/unix/sysv/linux/isatty.c new file mode 100644 index 0000000000..3faaec5e66 --- /dev/null +++ b/sysdeps/unix/sysv/linux/isatty.c @@ -0,0 +1,29 @@ +/* Test whether a file descriptor refers to a terminal. Linux version. + Copyright (C) 1991-2025 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#include + +/* Return 1 if FD is a terminal, 0 if not. This simply does a + TCGETS2 ioctl into a dummy buffer without parsing the result. */ +int +__isatty (int fd) +{ + struct termios2 k_termios; + return INLINE_SYSCALL_CALL (ioctl, fd, TCGETS2, &k_termios) == 0; +} +weak_alias (__isatty, isatty) diff --git a/sysdeps/unix/sysv/linux/isatty_nostatus.c b/sysdeps/unix/sysv/linux/isatty_nostatus.c index 7f110be00c..406decba62 100644 --- a/sysdeps/unix/sysv/linux/isatty_nostatus.c +++ b/sysdeps/unix/sysv/linux/isatty_nostatus.c @@ -15,15 +15,12 @@ License along with the GNU C Library; if not, see . */ -#include -#include -#include -#include +#include /* Return 1 if FD is a terminal, 0 if not, without changing errno */ int __isatty_nostatus (int fd) { - struct __kernel_termios k_termios; - return INTERNAL_SYSCALL_CALL (ioctl, fd, TCGETS, &k_termios) == 0; + struct termios2 k_termios; + return INTERNAL_SYSCALL_CALL (ioctl, fd, TCGETS2, &k_termios) == 0; } diff --git a/sysdeps/unix/sysv/linux/kernel-features.h b/sysdeps/unix/sysv/linux/kernel-features.h index 86b2d3ce51..a49a9159cf 100644 --- a/sysdeps/unix/sysv/linux/kernel-features.h +++ b/sysdeps/unix/sysv/linux/kernel-features.h @@ -54,6 +54,10 @@ configurations). */ #define __ASSUME_SET_ROBUST_LIST 1 +/* The termios2 interface was introduced across all architectures except + Alpha in kernel 2.6.22. */ +#define __ASSUME_TERMIOS2 1 + /* Support for various CLOEXEC and NONBLOCK flags was added in 2.6.27. */ #define __ASSUME_IN_NONBLOCK 1 diff --git a/sysdeps/unix/sysv/linux/loongarch/lp64/libc.abilist b/sysdeps/unix/sysv/linux/loongarch/lp64/libc.abilist index 927fc21445..6ab4968d17 100644 --- a/sysdeps/unix/sysv/linux/loongarch/lp64/libc.abilist +++ b/sysdeps/unix/sysv/linux/loongarch/lp64/libc.abilist @@ -2273,6 +2273,11 @@ GLIBC_2.41 sched_getattr F GLIBC_2.41 sched_setattr F GLIBC_2.42 __inet_ntop_chk F GLIBC_2.42 __inet_pton_chk F +GLIBC_2.42 cfgetispeed F +GLIBC_2.42 cfgetospeed F +GLIBC_2.42 cfsetispeed F +GLIBC_2.42 cfsetospeed F +GLIBC_2.42 cfsetspeed F GLIBC_2.42 pthread_gettid_np F GLIBC_2.42 uabs F GLIBC_2.42 uimaxabs F diff --git a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist index 74da49d9da..e553bdc8a3 100644 --- a/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist +++ b/sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist @@ -2785,6 +2785,11 @@ GLIBC_2.41 sched_getattr F GLIBC_2.41 sched_setattr F GLIBC_2.42 __inet_ntop_chk F GLIBC_2.42 __inet_pton_chk F +GLIBC_2.42 cfgetispeed F +GLIBC_2.42 cfgetospeed F +GLIBC_2.42 cfsetispeed F +GLIBC_2.42 cfsetospeed F +GLIBC_2.42 cfsetspeed F GLIBC_2.42 pthread_gettid_np F GLIBC_2.42 uabs F GLIBC_2.42 uimaxabs F diff --git a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist index e5d678111f..1239f0d7a0 100644 --- a/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist +++ b/sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist @@ -2952,6 +2952,11 @@ GLIBC_2.41 sched_getattr F GLIBC_2.41 sched_setattr F GLIBC_2.42 __inet_ntop_chk F GLIBC_2.42 __inet_pton_chk F +GLIBC_2.42 cfgetispeed F +GLIBC_2.42 cfgetospeed F +GLIBC_2.42 cfsetispeed F +GLIBC_2.42 cfsetospeed F +GLIBC_2.42 cfsetspeed F GLIBC_2.42 pthread_gettid_np F GLIBC_2.42 uabs F GLIBC_2.42 uimaxabs F diff --git a/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist b/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist index 4dbd4b6045..943e89a45f 100644 --- a/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist +++ b/sysdeps/unix/sysv/linux/microblaze/be/libc.abilist @@ -2838,6 +2838,11 @@ GLIBC_2.41 sched_getattr F GLIBC_2.41 sched_setattr F GLIBC_2.42 __inet_ntop_chk F GLIBC_2.42 __inet_pton_chk F +GLIBC_2.42 cfgetispeed F +GLIBC_2.42 cfgetospeed F +GLIBC_2.42 cfsetispeed F +GLIBC_2.42 cfsetospeed F +GLIBC_2.42 cfsetspeed F GLIBC_2.42 pthread_gettid_np F GLIBC_2.42 uabs F GLIBC_2.42 uimaxabs F diff --git a/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist b/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist index c5965bb50c..9c303d9d9a 100644 --- a/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist +++ b/sysdeps/unix/sysv/linux/microblaze/le/libc.abilist @@ -2835,6 +2835,11 @@ GLIBC_2.41 sched_getattr F GLIBC_2.41 sched_setattr F GLIBC_2.42 __inet_ntop_chk F GLIBC_2.42 __inet_pton_chk F +GLIBC_2.42 cfgetispeed F +GLIBC_2.42 cfgetospeed F +GLIBC_2.42 cfsetispeed F +GLIBC_2.42 cfsetospeed F +GLIBC_2.42 cfsetspeed F GLIBC_2.42 pthread_gettid_np F GLIBC_2.42 uabs F GLIBC_2.42 uimaxabs F diff --git a/sysdeps/unix/sysv/linux/mips/Versions b/sysdeps/unix/sysv/linux/mips/Versions index 9ea0fa65a4..48f0037fe6 100644 --- a/sysdeps/unix/sysv/linux/mips/Versions +++ b/sysdeps/unix/sysv/linux/mips/Versions @@ -26,6 +26,10 @@ libc { pthread_attr_setstack; pthread_attr_setstacksize; } + GLIBC_2.42 { + tcgetattr; + tcsetattr; + } GLIBC_PRIVATE { # nptl/pthread_cond_timedwait.c uses INTERNAL_VSYSCALL(clock_gettime). __vdso_clock_gettime; diff --git a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist index 10715e0777..6eb6fd476b 100644 --- a/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist +++ b/sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist @@ -2913,7 +2913,14 @@ GLIBC_2.41 sched_getattr F GLIBC_2.41 sched_setattr F GLIBC_2.42 __inet_ntop_chk F GLIBC_2.42 __inet_pton_chk F +GLIBC_2.42 cfgetispeed F +GLIBC_2.42 cfgetospeed F +GLIBC_2.42 cfsetispeed F +GLIBC_2.42 cfsetospeed F +GLIBC_2.42 cfsetspeed F GLIBC_2.42 pthread_gettid_np F +GLIBC_2.42 tcgetattr F +GLIBC_2.42 tcsetattr F GLIBC_2.42 uabs F GLIBC_2.42 uimaxabs F GLIBC_2.42 ulabs F diff --git a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist index 3d229b9853..58a43bb9b3 100644 --- a/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist +++ b/sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist @@ -2911,7 +2911,14 @@ GLIBC_2.41 sched_getattr F GLIBC_2.41 sched_setattr F GLIBC_2.42 __inet_ntop_chk F GLIBC_2.42 __inet_pton_chk F +GLIBC_2.42 cfgetispeed F +GLIBC_2.42 cfgetospeed F +GLIBC_2.42 cfsetispeed F +GLIBC_2.42 cfsetospeed F +GLIBC_2.42 cfsetspeed F GLIBC_2.42 pthread_gettid_np F +GLIBC_2.42 tcgetattr F +GLIBC_2.42 tcsetattr F GLIBC_2.42 uabs F GLIBC_2.42 uimaxabs F GLIBC_2.42 ulabs F diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist index e4cb45275b..abab2ad807 100644 --- a/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist +++ b/sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist @@ -2919,7 +2919,14 @@ GLIBC_2.41 sched_getattr F GLIBC_2.41 sched_setattr F GLIBC_2.42 __inet_ntop_chk F GLIBC_2.42 __inet_pton_chk F +GLIBC_2.42 cfgetispeed F +GLIBC_2.42 cfgetospeed F +GLIBC_2.42 cfsetispeed F +GLIBC_2.42 cfsetospeed F +GLIBC_2.42 cfsetspeed F GLIBC_2.42 pthread_gettid_np F +GLIBC_2.42 tcgetattr F +GLIBC_2.42 tcsetattr F GLIBC_2.42 uabs F GLIBC_2.42 uimaxabs F GLIBC_2.42 ulabs F diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist index 8a32d2585d..2e31f6eed6 100644 --- a/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist +++ b/sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist @@ -2821,7 +2821,14 @@ GLIBC_2.41 sched_getattr F GLIBC_2.41 sched_setattr F GLIBC_2.42 __inet_ntop_chk F GLIBC_2.42 __inet_pton_chk F +GLIBC_2.42 cfgetispeed F +GLIBC_2.42 cfgetospeed F +GLIBC_2.42 cfsetispeed F +GLIBC_2.42 cfsetospeed F +GLIBC_2.42 cfsetspeed F GLIBC_2.42 pthread_gettid_np F +GLIBC_2.42 tcgetattr F +GLIBC_2.42 tcsetattr F GLIBC_2.42 uabs F GLIBC_2.42 uimaxabs F GLIBC_2.42 ulabs F diff --git a/sysdeps/unix/sysv/linux/kernel_termios.h b/sysdeps/unix/sysv/linux/mips/termios_arch.h similarity index 54% rename from sysdeps/unix/sysv/linux/kernel_termios.h rename to sysdeps/unix/sysv/linux/mips/termios_arch.h index f02a197518..392d9aa792 100644 --- a/sysdeps/unix/sysv/linux/kernel_termios.h +++ b/sysdeps/unix/sysv/linux/mips/termios_arch.h @@ -1,4 +1,6 @@ -/* Copyright (C) 1997-2025 Free Software Foundation, Inc. +/* Architectural parameters for Linux termios - MIPS version + + Copyright (C) 1991-2025 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -15,23 +17,18 @@ License along with the GNU C Library; if not, see . */ -#ifndef _KERNEL_TERMIOS_H -#define _KERNEL_TERMIOS_H 1 -/* The following corresponds to the values from the Linux 2.1.20 kernel. */ +#define _TERMIOS2_NCCS 23 +#define _HAVE_TERMIOS2_C_CC_BEFORE_C_LINE 0 -#define __KERNEL_NCCS 19 +#define _HAVE_STRUCT_OLD_TERMIOS 1 -struct __kernel_termios - { - tcflag_t c_iflag; /* input mode flags */ - tcflag_t c_oflag; /* output mode flags */ - tcflag_t c_cflag; /* control mode flags */ - tcflag_t c_lflag; /* local mode flags */ - cc_t c_line; /* line discipline */ - cc_t c_cc[__KERNEL_NCCS]; /* control characters */ - }; - -#define _HAVE_C_ISPEED 0 -#define _HAVE_C_OSPEED 0 - -#endif /* kernel_termios.h */ +#define OLD_NCCS 32 +struct old_termios +{ + tcflag_t c_iflag; /* input mode flags */ + tcflag_t c_oflag; /* output mode flags */ + tcflag_t c_cflag; /* control mode flags */ + tcflag_t c_lflag; /* local mode flags */ + cc_t c_line; /* line discipline */ + cc_t c_cc[OLD_NCCS]; /* control characters */ +}; diff --git a/sysdeps/unix/sysv/linux/old_termios.h b/sysdeps/unix/sysv/linux/old_termios.h new file mode 100644 index 0000000000..56d19baee2 --- /dev/null +++ b/sysdeps/unix/sysv/linux/old_termios.h @@ -0,0 +1,23 @@ +/* old_termios.h for Linux other than MIPS and SPARC + + Copyright (C) 2025 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +/* By default, no old termios structure */ +#define _HAVE_STRUCT_OLD_TERMIOS 0 +#define OLD_NCCS NCCS +typedef struct termios old_termios_t; diff --git a/sysdeps/unix/sysv/linux/or1k/libc.abilist b/sysdeps/unix/sysv/linux/or1k/libc.abilist index 64dac95b2a..b54c078b52 100644 --- a/sysdeps/unix/sysv/linux/or1k/libc.abilist +++ b/sysdeps/unix/sysv/linux/or1k/libc.abilist @@ -2263,6 +2263,11 @@ GLIBC_2.41 sched_getattr F GLIBC_2.41 sched_setattr F GLIBC_2.42 __inet_ntop_chk F GLIBC_2.42 __inet_pton_chk F +GLIBC_2.42 cfgetispeed F +GLIBC_2.42 cfgetospeed F +GLIBC_2.42 cfsetispeed F +GLIBC_2.42 cfsetospeed F +GLIBC_2.42 cfsetspeed F GLIBC_2.42 pthread_gettid_np F GLIBC_2.42 uabs F GLIBC_2.42 uimaxabs F diff --git a/sysdeps/unix/sysv/linux/powerpc/bits/termios-c_cflag.h b/sysdeps/unix/sysv/linux/powerpc/bits/termios-c_cflag.h index 9ea8cfbe72..a90d581484 100644 --- a/sysdeps/unix/sysv/linux/powerpc/bits/termios-c_cflag.h +++ b/sysdeps/unix/sysv/linux/powerpc/bits/termios-c_cflag.h @@ -35,5 +35,7 @@ #define CLOCAL 00100000 #ifdef __USE_MISC -# define ADDRB 04000000000 +# define ADDRB 04000000000 +# define CMSPAR 010000000000 /* Mark or space (stick) parity. */ +# define CRTSCTS 020000000000 /* Flow control. */ #endif diff --git a/sysdeps/unix/sysv/linux/powerpc/bits/termios-baud.h b/sysdeps/unix/sysv/linux/powerpc/bits/termios-cbaud.h similarity index 58% rename from sysdeps/unix/sysv/linux/powerpc/bits/termios-baud.h rename to sysdeps/unix/sysv/linux/powerpc/bits/termios-cbaud.h index 374d9f8949..7bcbba441a 100644 --- a/sysdeps/unix/sysv/linux/powerpc/bits/termios-baud.h +++ b/sysdeps/unix/sysv/linux/powerpc/bits/termios-cbaud.h @@ -17,29 +17,29 @@ . */ #ifndef _TERMIOS_H -# error "Never include directly; use instead." +# error "Never include directly; use instead." #endif #ifdef __USE_MISC -# define CBAUD 0000377 -# define CBAUDEX 0000020 -# define CMSPAR 010000000000 /* mark or space (stick) parity */ -# define CRTSCTS 020000000000 /* flow control */ +# define CBAUD 000000377 +# define CBAUDEX 000000020 +# define CIBAUD 077600000 +# define IBSHIFT 16 #endif -#define B57600 00020 -#define B115200 00021 -#define B230400 00022 -#define B460800 00023 -#define B500000 00024 -#define B576000 00025 -#define B921600 00026 -#define B1000000 00027 -#define B1152000 00030 -#define B1500000 00031 -#define B2000000 00032 -#define B2500000 00033 -#define B3000000 00034 -#define B3500000 00035 -#define B4000000 00036 -#define __MAX_BAUD B4000000 +#define __B57600 00020 +#define __B115200 00021 +#define __B230400 00022 +#define __B460800 00023 +#define __B500000 00024 +#define __B576000 00025 +#define __B921600 00026 +#define __B1000000 00027 +#define __B1152000 00030 +#define __B1500000 00031 +#define __B2000000 00032 +#define __B2500000 00033 +#define __B3000000 00034 +#define __B3500000 00035 +#define __B4000000 00036 +#define __BOTHER 00037 diff --git a/sysdeps/unix/sysv/linux/powerpc/kernel_termios.h b/sysdeps/unix/sysv/linux/powerpc/kernel_termios.h deleted file mode 100644 index f6ea570ebe..0000000000 --- a/sysdeps/unix/sysv/linux/powerpc/kernel_termios.h +++ /dev/null @@ -1,53 +0,0 @@ -/* Copyright (C) 1997-2025 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - . */ - -#ifndef _KERNEL_TERMIOS_H -#define _KERNEL_TERMIOS_H 1 - -/* We need the definition of tcflag_t, cc_t, and speed_t. */ -#include - -#define __KERNEL_NCCS 19 - -struct __kernel_termios - { - tcflag_t c_iflag; /* input mode flags */ - tcflag_t c_oflag; /* output mode flags */ - tcflag_t c_cflag; /* control mode flags */ - tcflag_t c_lflag; /* local mode flags */ - cc_t c_cc[__KERNEL_NCCS]; /* control characters */ - cc_t c_line; /* line discipline */ - speed_t c_ispeed; /* input speed */ - speed_t c_ospeed; /* output speed */ - }; - -#define _HAVE_C_ISPEED 1 -#define _HAVE_C_OSPEED 1 - -/* We have the kernel termios structure, so we can presume this code knows - what it's doing... */ - -#undef TCGETS -#undef TCSETS -#undef TCSETSW -#undef TCSETSF -#define TCGETS _IOR ('t', 19, struct __kernel_termios) -#define TCSETS _IOW ('t', 20, struct __kernel_termios) -#define TCSETSW _IOW ('t', 21, struct __kernel_termios) -#define TCSETSF _IOW ('t', 22, struct __kernel_termios) - -#endif /* kernel_termios.h */ diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist index cc5e93c77c..c30e17cdfc 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist @@ -3142,6 +3142,11 @@ GLIBC_2.41 sched_getattr F GLIBC_2.41 sched_setattr F GLIBC_2.42 __inet_ntop_chk F GLIBC_2.42 __inet_pton_chk F +GLIBC_2.42 cfgetispeed F +GLIBC_2.42 cfgetospeed F +GLIBC_2.42 cfsetispeed F +GLIBC_2.42 cfsetospeed F +GLIBC_2.42 cfsetspeed F GLIBC_2.42 pthread_gettid_np F GLIBC_2.42 uabs F GLIBC_2.42 uimaxabs F diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist index 9814997083..f3c0c02052 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist @@ -3187,6 +3187,11 @@ GLIBC_2.41 sched_getattr F GLIBC_2.41 sched_setattr F GLIBC_2.42 __inet_ntop_chk F GLIBC_2.42 __inet_pton_chk F +GLIBC_2.42 cfgetispeed F +GLIBC_2.42 cfgetospeed F +GLIBC_2.42 cfsetispeed F +GLIBC_2.42 cfsetospeed F +GLIBC_2.42 cfsetspeed F GLIBC_2.42 pthread_gettid_np F GLIBC_2.42 uabs F GLIBC_2.42 uimaxabs F diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist index 7f46295c11..6e1d141ca7 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist @@ -2896,6 +2896,11 @@ GLIBC_2.41 sched_getattr F GLIBC_2.41 sched_setattr F GLIBC_2.42 __inet_ntop_chk F GLIBC_2.42 __inet_pton_chk F +GLIBC_2.42 cfgetispeed F +GLIBC_2.42 cfgetospeed F +GLIBC_2.42 cfsetispeed F +GLIBC_2.42 cfsetospeed F +GLIBC_2.42 cfsetspeed F GLIBC_2.42 pthread_gettid_np F GLIBC_2.42 uabs F GLIBC_2.42 uimaxabs F diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist index f24f81bb5f..441296c7e8 100644 --- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist @@ -2972,6 +2972,11 @@ GLIBC_2.41 sched_getattr F GLIBC_2.41 sched_setattr F GLIBC_2.42 __inet_ntop_chk F GLIBC_2.42 __inet_pton_chk F +GLIBC_2.42 cfgetispeed F +GLIBC_2.42 cfgetospeed F +GLIBC_2.42 cfsetispeed F +GLIBC_2.42 cfsetospeed F +GLIBC_2.42 cfsetspeed F GLIBC_2.42 pthread_gettid_np F GLIBC_2.42 uabs F GLIBC_2.42 uimaxabs F diff --git a/sysdeps/unix/sysv/linux/sparc/bits/termios-struct.h b/sysdeps/unix/sysv/linux/powerpc/termios_arch.h similarity index 51% rename from sysdeps/unix/sysv/linux/sparc/bits/termios-struct.h rename to sysdeps/unix/sysv/linux/powerpc/termios_arch.h index 269ca9d675..20025f2549 100644 --- a/sysdeps/unix/sysv/linux/sparc/bits/termios-struct.h +++ b/sysdeps/unix/sysv/linux/powerpc/termios_arch.h @@ -1,5 +1,6 @@ -/* struct termios definition. Linux/sparc version. - Copyright (C) 2019-2025 Free Software Foundation, Inc. +/* Architectural parameters for Linux termios - Alpha/PowerPC version + + Copyright (C) 1997-2025 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -13,22 +14,13 @@ Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library. If not, see + License along with the GNU C Library; if not, see . */ -#ifndef _TERMIOS_H -# error "Never include directly; use instead." +#ifndef TERMIOS_INTERNALS_H +# error " should only be included from " #endif -#define NCCS 17 -struct termios - { - tcflag_t c_iflag; /* input mode flags */ - tcflag_t c_oflag; /* output mode flags */ - tcflag_t c_cflag; /* control mode flags */ - tcflag_t c_lflag; /* local mode flags */ - cc_t c_line; /* line discipline */ - cc_t c_cc[NCCS]; /* control characters */ -#define _HAVE_STRUCT_TERMIOS_C_ISPEED 0 -#define _HAVE_STRUCT_TERMIOS_C_OSPEED 0 - }; +#define _TERMIOS2_NCCS 19 +#define _HAVE_TERMIOS2_C_CC_BEFORE_C_LINE 1 +#define _HAVE_STRUCT_OLD_TERMIOS 0 diff --git a/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist b/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist index 9330c7ab76..bcc0ed8d6a 100644 --- a/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist +++ b/sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist @@ -2516,6 +2516,11 @@ GLIBC_2.41 sched_getattr F GLIBC_2.41 sched_setattr F GLIBC_2.42 __inet_ntop_chk F GLIBC_2.42 __inet_pton_chk F +GLIBC_2.42 cfgetispeed F +GLIBC_2.42 cfgetospeed F +GLIBC_2.42 cfsetispeed F +GLIBC_2.42 cfsetospeed F +GLIBC_2.42 cfsetspeed F GLIBC_2.42 pthread_gettid_np F GLIBC_2.42 uabs F GLIBC_2.42 uimaxabs F diff --git a/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist b/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist index ea4555d39e..d55b553c0e 100644 --- a/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist +++ b/sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist @@ -2716,6 +2716,11 @@ GLIBC_2.41 sched_getattr F GLIBC_2.41 sched_setattr F GLIBC_2.42 __inet_ntop_chk F GLIBC_2.42 __inet_pton_chk F +GLIBC_2.42 cfgetispeed F +GLIBC_2.42 cfgetospeed F +GLIBC_2.42 cfsetispeed F +GLIBC_2.42 cfsetospeed F +GLIBC_2.42 cfsetspeed F GLIBC_2.42 pthread_gettid_np F GLIBC_2.42 uabs F GLIBC_2.42 uimaxabs F diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist index 3e625fa4e9..a45b8874f0 100644 --- a/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist +++ b/sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist @@ -3140,6 +3140,11 @@ GLIBC_2.41 sched_getattr F GLIBC_2.41 sched_setattr F GLIBC_2.42 __inet_ntop_chk F GLIBC_2.42 __inet_pton_chk F +GLIBC_2.42 cfgetispeed F +GLIBC_2.42 cfgetospeed F +GLIBC_2.42 cfsetispeed F +GLIBC_2.42 cfsetospeed F +GLIBC_2.42 cfsetspeed F GLIBC_2.42 pthread_gettid_np F GLIBC_2.42 uabs F GLIBC_2.42 uimaxabs F diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist index 46b4a04f65..17483dcc48 100644 --- a/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist +++ b/sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist @@ -2933,6 +2933,11 @@ GLIBC_2.41 sched_getattr F GLIBC_2.41 sched_setattr F GLIBC_2.42 __inet_ntop_chk F GLIBC_2.42 __inet_pton_chk F +GLIBC_2.42 cfgetispeed F +GLIBC_2.42 cfgetospeed F +GLIBC_2.42 cfsetispeed F +GLIBC_2.42 cfsetospeed F +GLIBC_2.42 cfsetspeed F GLIBC_2.42 pthread_gettid_np F GLIBC_2.42 uabs F GLIBC_2.42 uimaxabs F diff --git a/sysdeps/unix/sysv/linux/sh/be/libc.abilist b/sysdeps/unix/sysv/linux/sh/be/libc.abilist index 36a94c9210..cb62b6e083 100644 --- a/sysdeps/unix/sysv/linux/sh/be/libc.abilist +++ b/sysdeps/unix/sysv/linux/sh/be/libc.abilist @@ -2832,6 +2832,11 @@ GLIBC_2.41 sched_getattr F GLIBC_2.41 sched_setattr F GLIBC_2.42 __inet_ntop_chk F GLIBC_2.42 __inet_pton_chk F +GLIBC_2.42 cfgetispeed F +GLIBC_2.42 cfgetospeed F +GLIBC_2.42 cfsetispeed F +GLIBC_2.42 cfsetospeed F +GLIBC_2.42 cfsetspeed F GLIBC_2.42 pthread_gettid_np F GLIBC_2.42 uabs F GLIBC_2.42 uimaxabs F diff --git a/sysdeps/unix/sysv/linux/sh/le/libc.abilist b/sysdeps/unix/sysv/linux/sh/le/libc.abilist index f79aba6aab..ee6f2d0170 100644 --- a/sysdeps/unix/sysv/linux/sh/le/libc.abilist +++ b/sysdeps/unix/sysv/linux/sh/le/libc.abilist @@ -2829,6 +2829,11 @@ GLIBC_2.41 sched_getattr F GLIBC_2.41 sched_setattr F GLIBC_2.42 __inet_ntop_chk F GLIBC_2.42 __inet_pton_chk F +GLIBC_2.42 cfgetispeed F +GLIBC_2.42 cfgetospeed F +GLIBC_2.42 cfsetispeed F +GLIBC_2.42 cfsetospeed F +GLIBC_2.42 cfsetspeed F GLIBC_2.42 pthread_gettid_np F GLIBC_2.42 uabs F GLIBC_2.42 uimaxabs F diff --git a/sysdeps/unix/sysv/linux/sparc/Versions b/sysdeps/unix/sysv/linux/sparc/Versions index f127bdf0b8..7dd61a54c4 100644 --- a/sysdeps/unix/sysv/linux/sparc/Versions +++ b/sysdeps/unix/sysv/linux/sparc/Versions @@ -29,6 +29,10 @@ libc { __getshmlba; } + GLIBC_2.42 { + tcgetattr; + tcsetattr; + } GLIBC_PRIVATE { # nptl/pthread_cond_timedwait.c uses INTERNAL_VSYSCALL(clock_gettime). __vdso_clock_gettime; diff --git a/sysdeps/unix/sysv/linux/sparc/bits/termios-baud.h b/sysdeps/unix/sysv/linux/sparc/bits/termios-cbaud.h similarity index 57% rename from sysdeps/unix/sysv/linux/sparc/bits/termios-baud.h rename to sysdeps/unix/sysv/linux/sparc/bits/termios-cbaud.h index 677db7ba11..34eba18184 100644 --- a/sysdeps/unix/sysv/linux/sparc/bits/termios-baud.h +++ b/sysdeps/unix/sysv/linux/sparc/bits/termios-cbaud.h @@ -17,30 +17,29 @@ . */ #ifndef _TERMIOS_H -# error "Never include directly; use instead." +# error "Never include directly; use instead." #endif #ifdef __USE_MISC # define CBAUD 0x0000100f # define CBAUDEX 0x00001000 -# define CIBAUD 0x100f0000 /* input baud rate (not used) */ -# define CMSPAR 0x40000000 /* mark or space (stick) parity */ -# define CRTSCTS 0x80000000 /* flow control */ +# define CIBAUD 0x100f0000 /* input baud rate */ +# define IBSHIFT 16 #endif -#define B57600 0x00001001 -#define B115200 0x00001002 -#define B230400 0x00001003 -#define B460800 0x00001004 -#define B76800 0x00001005 -#define B153600 0x00001006 -#define B307200 0x00001007 -#define B614400 0x00001008 -#define B921600 0x00001009 -#define B500000 0x0000100a -#define B576000 0x0000100b -#define B1000000 0x0000100c -#define B1152000 0x0000100d -#define B1500000 0x0000100e -#define B2000000 0x0000100f -#define __MAX_BAUD B2000000 +#define __B57600 0x00001001 +#define __B115200 0x00001002 +#define __B230400 0x00001003 +#define __B460800 0x00001004 +#define __B76800 0x00001005 +#define __B153600 0x00001006 +#define __B307200 0x00001007 +#define __B614400 0x00001008 +#define __B921600 0x00001009 +#define __B500000 0x0000100a +#define __B576000 0x0000100b +#define __B1000000 0x0000100c +#define __B1152000 0x0000100d +#define __B1500000 0x0000100e +#define __B2000000 0x0000100f +#define __BOTHER 0x00001000 diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist index 4a6acc08e0..943e130d3a 100644 --- a/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist +++ b/sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist @@ -3161,7 +3161,14 @@ GLIBC_2.41 sched_getattr F GLIBC_2.41 sched_setattr F GLIBC_2.42 __inet_ntop_chk F GLIBC_2.42 __inet_pton_chk F +GLIBC_2.42 cfgetispeed F +GLIBC_2.42 cfgetospeed F +GLIBC_2.42 cfsetispeed F +GLIBC_2.42 cfsetospeed F +GLIBC_2.42 cfsetspeed F GLIBC_2.42 pthread_gettid_np F +GLIBC_2.42 tcgetattr F +GLIBC_2.42 tcsetattr F GLIBC_2.42 uabs F GLIBC_2.42 uimaxabs F GLIBC_2.42 ulabs F diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist index 931109dab1..1017babb1d 100644 --- a/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist +++ b/sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist @@ -2797,7 +2797,14 @@ GLIBC_2.41 sched_getattr F GLIBC_2.41 sched_setattr F GLIBC_2.42 __inet_ntop_chk F GLIBC_2.42 __inet_pton_chk F +GLIBC_2.42 cfgetispeed F +GLIBC_2.42 cfgetospeed F +GLIBC_2.42 cfsetispeed F +GLIBC_2.42 cfsetospeed F +GLIBC_2.42 cfsetspeed F GLIBC_2.42 pthread_gettid_np F +GLIBC_2.42 tcgetattr F +GLIBC_2.42 tcsetattr F GLIBC_2.42 uabs F GLIBC_2.42 uimaxabs F GLIBC_2.42 ulabs F diff --git a/sysdeps/unix/sysv/linux/sparc/kernel_termios.h b/sysdeps/unix/sysv/linux/sparc/termios_arch.h similarity index 51% rename from sysdeps/unix/sysv/linux/sparc/kernel_termios.h rename to sysdeps/unix/sysv/linux/sparc/termios_arch.h index 401079c4e5..f3b3f656d1 100644 --- a/sysdeps/unix/sysv/linux/sparc/kernel_termios.h +++ b/sysdeps/unix/sysv/linux/sparc/termios_arch.h @@ -1,4 +1,6 @@ -/* Copyright (C) 1997-2025 Free Software Foundation, Inc. +/* Architectural parameters for Linux termios - SPARC version + + Copyright (C) 1991-2025 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -15,26 +17,18 @@ License along with the GNU C Library; if not, see . */ -#ifndef _KERNEL_TERMIOS_H -#define _KERNEL_TERMIOS_H 1 -/* The following corresponds to the values from the Linux 2.1.20 kernel. */ +#define _TERMIOS2_NCCS 19 +#define _HAVE_TERMIOS2_C_CC_BEFORE_C_LINE 0 -/* We need the definition of tcflag_t, cc_t, and speed_t. */ -#include +#define _HAVE_STRUCT_OLD_TERMIOS 1 -#define __KERNEL_NCCS 17 - -struct __kernel_termios - { - tcflag_t c_iflag; /* input mode flags */ - tcflag_t c_oflag; /* output mode flags */ - tcflag_t c_cflag; /* control mode flags */ - tcflag_t c_lflag; /* local mode flags */ - cc_t c_line; /* line discipline */ - cc_t c_cc[__KERNEL_NCCS]; /* control characters */ - }; - -#define _HAVE_C_ISPEED 0 -#define _HAVE_C_OSPEED 0 - -#endif /* kernel_termios.h */ +#define OLD_NCCS 17 +struct old_termios +{ + tcflag_t c_iflag; /* input mode flags */ + tcflag_t c_oflag; /* output mode flags */ + tcflag_t c_cflag; /* control mode flags */ + tcflag_t c_lflag; /* local mode flags */ + cc_t c_line; /* line discipline */ + cc_t c_cc[OLD_NCCS]; /* control characters */ +}; diff --git a/sysdeps/unix/sysv/linux/speed.c b/sysdeps/unix/sysv/linux/speed.c index 017f74177f..c9f4bb9d3f 100644 --- a/sysdeps/unix/sysv/linux/speed.c +++ b/sysdeps/unix/sysv/linux/speed.c @@ -16,82 +16,347 @@ License along with the GNU C Library; if not, see . */ -#include -#include -#include -#include +#include -/* This is a gross hack around a kernel bug. If the cfsetispeed functions - is called with the SPEED argument set to zero this means use the same - speed as for output. But we don't have independent input and output - speeds and therefore cannot record this. +/* Conversions between legacy c_cflag fields and actual baud rates */ - We use an unused bit in the `c_iflag' field to keep track of this - use of `cfsetispeed'. The value here must correspond to the one used - in `tcsetattr.c'. */ -#define IBAUD0 020000000000 +/* These expressions may seem complicated; the _cbix() macro + compresses the CBAUD field into an index in the range 0-31. On most + Linux platforms, the CBAUD field is 5 bits, but the topmost bit + indicated by CBAUDEX, is discontinous with the rest. + + The resulting masks look like: + + Alpha PowerPC others + + CBAUD 0x001f 0x00ff 0x100f + CBAUDEX 0x0000 0x0010 0x1000 + + LOWCBAUD 0x001f 0x000f 0x000f + CBAUDMASK 0x001f 0x001f 0x100f + + CBAUDMASK is used to test for invalid values passed to the + compatibility functions or in termios::c_cflag on PowerPC. + + The divide-multiply sequence in the _cbix() macro gets converted + to shift and masks as necessary by the compiler. */ + +#define LOWCBAUD (CBAUD & (CBAUDEX-1)) +#define _cbix(x) (((x) & LOWCBAUD) | \ + (CBAUDEX ? ((x) & CBAUDEX)/CBAUDEX * (LOWCBAUD+1) : 0)) +#define CBAUDMASK (LOWCBAUD | CBAUDEX) + +/* Compile time sanity checks for broken CBAUD or CIBAUD definitions */ +#if CIBAUD != (CBAUD << IBSHIFT) +# error "CIBAUD should == CBAUD << IBSHIFT" +#elif CBAUDEX & (CBAUDEX-1) +# error "CBAUDEX should either be 0 or a single bit" +#elif !(CBAUD & 1) +# error "The CBAUD field should start at bit 0" +#elif CBAUDEX & ~CBAUD +# error "CBAUD should include the CBAUDEX bit" +#endif + +speed_t +___cbaud_to_speed (tcflag_t c_cflag, speed_t other) +{ + static const speed_t cbaudix_to_speed [] = + { + [0 ... _cbix(CBAUDMASK)] = -1, + [_cbix(__B0)] = 0, + [_cbix(__B50)] = 50, + [_cbix(__B75)] = 75, + [_cbix(__B110)] = 110, + [_cbix(__B134)] = 134, + [_cbix(__B150)] = 150, + [_cbix(__B200)] = 200, + [_cbix(__B300)] = 300, + [_cbix(__B600)] = 600, + [_cbix(__B1200)] = 1200, + [_cbix(__B1800)] = 1800, + [_cbix(__B2400)] = 2400, + [_cbix(__B4800)] = 4800, + [_cbix(__B9600)] = 9600, + [_cbix(__B19200)] = 19200, + [_cbix(__B38400)] = 38400, + [_cbix(__B57600)] = 57600, + [_cbix(__B115200)] = 115200, + [_cbix(__B230400)] = 230400, + [_cbix(__B460800)] = 460800, + [_cbix(__B500000)] = 500000, + [_cbix(__B576000)] = 576000, + [_cbix(__B921600)] = 921600, + [_cbix(__B1000000)] = 1000000, + [_cbix(__B1152000)] = 1152000, + [_cbix(__B1500000)] = 1500000, + [_cbix(__B2000000)] = 2000000, +#ifdef __B7200 + [_cbix(__B7200)] = 7200, +#endif +#ifdef __B14400 + [_cbix(__B14400)] = 14400, +#endif +#ifdef __B28800 + [_cbix(__B28800)] = 28800, +#endif +#ifdef __B76800 + [_cbix(__B76800)] = 76800, +#endif +#ifdef __B153600 + [_cbix(__B153600)] = 153600, +#endif +#ifdef __B307200 + [_cbix(__B307200)] = 307200, +#endif +#ifdef __B614400 + [_cbix(__B614400)] = 614400, +#endif +#ifdef __B2500000 + [_cbix(__B2500000)] = 2500000, +#endif +#ifdef __B3000000 + [_cbix(__B3000000)] = 3000000, +#endif +#ifdef __B3500000 + [_cbix(__B3500000)] = 3500000, +#endif +#ifdef __B4000000 + [_cbix(__B4000000)] = 4000000, +#endif + }; + speed_t speed; + + if (c_cflag & (tcflag_t)(~CBAUDMASK)) + return other; + + speed = cbaudix_to_speed[_cbix(c_cflag)]; + return speed == (speed_t)-1 ? other : speed; +} + +tcflag_t +___speed_to_cbaud (speed_t speed) +{ + switch (speed) { + case 0: + return __B0; + case 50: + return __B50; + case 75: + return __B75; + case 110: + return __B110; + case 134: + return __B134; + case 150: + return __B150; + case 200: + return __B200; + case 300: + return __B300; + case 600: + return __B600; + case 1200: + return __B1200; + case 1800: + return __B1800; + case 2400: + return __B2400; + case 4800: + return __B4800; + case 9600: + return __B9600; + case 19200: + return __B19200; + case 38400: + return __B38400; + case 57600: + return __B57600; + case 115200: + return __B115200; + case 230400: + return __B230400; + case 460800: + return __B460800; + case 500000: + return __B500000; + case 576000: + return __B576000; + case 921600: + return __B921600; + case 1000000: + return __B1000000; + case 1152000: + return __B1152000; + case 1500000: + return __B1500000; + case 2000000: + return __B2000000; +#ifdef __B76800 + case 76800: + return __B76800; +#endif +#ifdef __B153600 + case 153600: + return __B153600; +#endif +#ifdef __B307200 + case 307200: + return __B307200; +#endif +#ifdef __B614400 + case 614400: + return __B614400; +#endif +#ifdef __B2500000 + case 2500000: + return __B2500000; +#endif +#ifdef __B3000000 + case 3000000: + return __B3000000; +#endif +#ifdef __B3500000 + case 3500000: + return __B3500000; +#endif +#ifdef __B4000000 + case 4000000: + return __B4000000; +#endif + default: + return __BOTHER; + } +} + + +/* Canonicalize the representation of speed fields in a kernel + termios2 structure. Specifically, if there is a valid legacy cbaud + representation (not __BOTHER), use it and propagate the + corresponding speed value to ispeed/ospeed, otherwise the other way + around if possible. Finally, if the input speed is zero, copy the + output speed to the input speed. + + The kernel doesn't do this canonicalization, which can affect + legacy utilities, so do it here. + + This is used by tcgetattr() and tcsetattr(). */ +void +___termios2_canonicalize_speeds (struct termios2 *k_termios_p) +{ + k_termios_p->c_ospeed = + ___cbaud_to_speed (cbaud (k_termios_p->c_cflag), k_termios_p->c_ospeed); + k_termios_p->c_ispeed = + ___cbaud_to_speed (cibaud (k_termios_p->c_cflag), k_termios_p->c_ispeed); + + if (!k_termios_p->c_ispeed) + k_termios_p->c_ispeed = k_termios_p->c_ospeed; + + k_termios_p->c_cflag &= ~(CBAUD | CIBAUD); + k_termios_p->c_cflag |= ___speed_to_cbaud (k_termios_p->c_ospeed); + k_termios_p->c_cflag |= ___speed_to_cbaud (k_termios_p->c_ispeed) << IBSHIFT; +} /* Return the output baud rate stored in *TERMIOS_P. */ speed_t -cfgetospeed (const struct termios *termios_p) +__cfgetospeed (const struct termios *termios_p) { - return termios_p->c_cflag & (CBAUD | CBAUDEX); + return termios_p->c_ospeed; } +versioned_symbol (libc, __cfgetospeed, cfgetospeed, GLIBC_2_42); -/* Return the input baud rate stored in *TERMIOS_P. - Although for Linux there is no difference between input and output - speed, the numerical 0 is a special case for the input baud rate. It - should set the input baud rate to the output baud rate. */ +/* Return the input baud rate stored in *TERMIOS_P. */ speed_t -cfgetispeed (const struct termios *termios_p) +__cfgetispeed (const struct termios *termios_p) { - return ((termios_p->c_iflag & IBAUD0) - ? 0 : termios_p->c_cflag & (CBAUD | CBAUDEX)); + return termios_p->c_ispeed; } +versioned_symbol (libc, __cfgetispeed, cfgetispeed, GLIBC_2_42); /* Set the output baud rate stored in *TERMIOS_P to SPEED. */ int -cfsetospeed (struct termios *termios_p, speed_t speed) +__cfsetospeed (struct termios *termios_p, speed_t speed) { - if ((speed & ~CBAUD) != 0 - && (speed < B57600 || speed > __MAX_BAUD)) + tcflag_t cbaud = ___speed_to_cbaud (speed); + + termios_p->c_ospeed = speed; + termios_p->c_cflag &= ~CBAUD; + termios_p->c_cflag |= cbaud; + + return 0; +} +versioned_symbol (libc, __cfsetospeed, cfsetospeed, GLIBC_2_42); + +/* Set the input baud rate stored in *TERMIOS_P to SPEED. */ +int +__cfsetispeed (struct termios *termios_p, speed_t speed) +{ + tcflag_t cbaud = ___speed_to_cbaud (speed); + + termios_p->c_ispeed = speed; + termios_p->c_cflag &= ~CIBAUD; + termios_p->c_cflag |= cbaud << IBSHIFT; + + return 0; +} +versioned_symbol (libc, __cfsetispeed, cfsetispeed, GLIBC_2_42); + +#if _TERMIOS_OLD_COMPAT + +/* Legacy versions which returns cbaud-encoded speed_t values */ + +speed_t +attribute_compat_text_section +__old_cfgetospeed (const old_termios_t *termios_p) +{ + return cbaud (termios_p->c_cflag); +} +compat_symbol (libc, __old_cfgetospeed, cfgetospeed, GLIBC_2_0); + +speed_t +attribute_compat_text_section +__old_cfgetispeed (const old_termios_t *termios_p) +{ + return cibaud (termios_p->c_cflag); +} +compat_symbol (libc, __old_cfgetispeed, cfgetispeed, GLIBC_2_0); + +int +attribute_compat_text_section +__old_cfsetospeed (old_termios_t *termios_p, speed_t speed) +{ + speed_t real_speed = ___cbaud_to_speed (speed, -1); + if (real_speed == (speed_t)-1) return INLINE_SYSCALL_ERROR_RETURN_VALUE (EINVAL); -#if _HAVE_STRUCT_TERMIOS_C_OSPEED - termios_p->c_ospeed = speed; +#if !_HAVE_STRUCT_OLD_TERMIOS + /* Otherwise this field doesn't exist in old_termios_t */ + termios_p->c_ospeed = real_speed; #endif - termios_p->c_cflag &= ~(CBAUD | CBAUDEX); + termios_p->c_cflag &= ~CBAUD; termios_p->c_cflag |= speed; return 0; } -libc_hidden_def (cfsetospeed) +compat_symbol (libc, __old_cfsetospeed, cfsetospeed, GLIBC_2_0); - -/* Set the input baud rate stored in *TERMIOS_P to SPEED. - Although for Linux there is no difference between input and output - speed, the numerical 0 is a special case for the input baud rate. It - should set the input baud rate to the output baud rate. */ int -cfsetispeed (struct termios *termios_p, speed_t speed) +attribute_compat_text_section +__old_cfsetispeed (old_termios_t *termios_p, speed_t speed) { - if ((speed & ~CBAUD) != 0 - && (speed < B57600 || speed > __MAX_BAUD)) + speed_t real_speed = ___cbaud_to_speed (speed, -1); + if (real_speed == (speed_t)-1) return INLINE_SYSCALL_ERROR_RETURN_VALUE (EINVAL); -#if _HAVE_STRUCT_TERMIOS_C_ISPEED - termios_p->c_ispeed = speed; +#if !_HAVE_STRUCT_OLD_TERMIOS + /* Otherwise this field doesn't exist in old_termios_t */ + termios_p->c_ispeed = real_speed; #endif - if (speed == 0) - termios_p->c_iflag |= IBAUD0; - else - { - termios_p->c_iflag &= ~IBAUD0; - termios_p->c_cflag &= ~(CBAUD | CBAUDEX); - termios_p->c_cflag |= speed; - } + termios_p->c_cflag &= ~CIBAUD; + termios_p->c_cflag |= speed << IBSHIFT; return 0; } -libc_hidden_def (cfsetispeed) +compat_symbol (libc, __old_cfsetispeed, cfsetispeed, GLIBC_2_0); + +#endif /* _TERMIOS_OLD_COMPAT */ diff --git a/sysdeps/unix/sysv/linux/tcgetattr.c b/sysdeps/unix/sysv/linux/tcgetattr.c index d672e0c3b1..ca175697a3 100644 --- a/sysdeps/unix/sysv/linux/tcgetattr.c +++ b/sysdeps/unix/sysv/linux/tcgetattr.c @@ -15,66 +15,56 @@ License along with the GNU C Library; if not, see . */ -#include -#include -#include -#include -#include -#include -#include - -/* The difference here is that the termios structure used in the - kernel is not the same as we use in the libc. Therefore we must - translate it here. */ -#include +#include /* Put the state of FD into *TERMIOS_P. */ int __tcgetattr (int fd, struct termios *termios_p) { - struct __kernel_termios k_termios; - int retval; + struct termios2 k_termios; + long int retval = INLINE_SYSCALL_CALL (ioctl, fd, TCGETS2, &k_termios); - retval = INLINE_SYSCALL (ioctl, 3, fd, TCGETS, &k_termios); - - if (__glibc_likely (retval == 0)) + if (__glibc_likely (retval != -1)) { - termios_p->c_iflag = k_termios.c_iflag; - termios_p->c_oflag = k_termios.c_oflag; - termios_p->c_cflag = k_termios.c_cflag; - termios_p->c_lflag = k_termios.c_lflag; - termios_p->c_line = k_termios.c_line; -#if _HAVE_STRUCT_TERMIOS_C_ISPEED -# if _HAVE_C_ISPEED - termios_p->c_ispeed = k_termios.c_ispeed; -# else - termios_p->c_ispeed = k_termios.c_cflag & (CBAUD | CBAUDEX); -# endif -#endif -#if _HAVE_STRUCT_TERMIOS_C_OSPEED -# if _HAVE_C_OSPEED - termios_p->c_ospeed = k_termios.c_ospeed; -# else - termios_p->c_ospeed = k_termios.c_cflag & (CBAUD | CBAUDEX); -# endif -#endif - if (sizeof (cc_t) == 1 || _POSIX_VDISABLE == 0 - || (unsigned char) _POSIX_VDISABLE == (unsigned char) -1) - memset (__mempcpy (&termios_p->c_cc[0], &k_termios.c_cc[0], - __KERNEL_NCCS * sizeof (cc_t)), - _POSIX_VDISABLE, (NCCS - __KERNEL_NCCS) * sizeof (cc_t)); - else - { - memcpy (&termios_p->c_cc[0], &k_termios.c_cc[0], - __KERNEL_NCCS * sizeof (cc_t)); + ___termios2_canonicalize_speeds (&k_termios); - for (size_t cnt = __KERNEL_NCCS; cnt < NCCS; ++cnt) - termios_p->c_cc[cnt] = _POSIX_VDISABLE; - } + memset (termios_p, 0, sizeof (*termios_p)); + termios_p->c_iflag = k_termios.c_iflag; + termios_p->c_oflag = k_termios.c_oflag; + termios_p->c_cflag = k_termios.c_cflag; + termios_p->c_lflag = k_termios.c_lflag; + termios_p->c_line = k_termios.c_line; + termios_p->c_ospeed = k_termios.c_ospeed; + termios_p->c_ispeed = k_termios.c_ispeed; + + copy_c_cc (termios_p->c_cc, NCCS, k_termios.c_cc, _TERMIOS2_NCCS); } return retval; } - libc_hidden_def (__tcgetattr) + +#if _TERMIOS_OLD_COMPAT && _HAVE_STRUCT_OLD_TERMIOS + +versioned_symbol (libc, __tcgetattr, tcgetattr, GLIBC_2_42); + +/* Legacy version for shorter struct termios */ +int +attribute_compat_text_section +__old_tcgetattr (int fd, old_termios_t *termios_p) +{ + struct termios new_termios; + int retval = __tcgetattr (fd, &new_termios); + if (__glibc_likely (retval != -1)) + { + memcpy (termios_p, &new_termios, sizeof (*termios_p)); + } + return retval; +} +compat_symbol (libc, __old_tcgetattr, tcgetattr, GLIBC_2_0); + +#else + weak_alias (__tcgetattr, tcgetattr) + +#endif diff --git a/sysdeps/unix/sysv/linux/tcsetattr.c b/sysdeps/unix/sysv/linux/tcsetattr.c index 49d9d245a0..4f07a03e66 100644 --- a/sysdeps/unix/sysv/linux/tcsetattr.c +++ b/sysdeps/unix/sysv/linux/tcsetattr.c @@ -15,67 +15,94 @@ License along with the GNU C Library; if not, see . */ -#include -#include -#include -#include -#include -#include - -/* The difference here is that the termios structure used in the - kernel is not the same as we use in the libc. Therefore we must - translate it here. */ -#include - - -/* This is a gross hack around a kernel bug. If the cfsetispeed functions - is called with the SPEED argument set to zero this means use the same - speed as for output. But we don't have independent input and output - speeds and therefore cannot record this. - - We use an unused bit in the `c_iflag' field to keep track of this - use of `cfsetispeed'. The value here must correspond to the one used - in `speed.c'. */ -#define IBAUD0 020000000000 +#include +#define static_assert_equal(x,y) _Static_assert ((x) == (y), #x " != " #y) /* Set the state of FD to *TERMIOS_P. */ int __tcsetattr (int fd, int optional_actions, const struct termios *termios_p) { - struct __kernel_termios k_termios; - unsigned long int cmd; + struct termios2 k_termios; + unsigned long cmd; - switch (optional_actions) - { - case TCSANOW: - cmd = TCSETS; - break; - case TCSADRAIN: - cmd = TCSETSW; - break; - case TCSAFLUSH: - cmd = TCSETSF; - break; - default: - return INLINE_SYSCALL_ERROR_RETURN_VALUE (EINVAL); - } + memset (&k_termios, 0, sizeof k_termios); - k_termios.c_iflag = termios_p->c_iflag & ~IBAUD0; + k_termios.c_iflag = termios_p->c_iflag; k_termios.c_oflag = termios_p->c_oflag; k_termios.c_cflag = termios_p->c_cflag; k_termios.c_lflag = termios_p->c_lflag; - k_termios.c_line = termios_p->c_line; -#if _HAVE_C_ISPEED && _HAVE_STRUCT_TERMIOS_C_ISPEED - k_termios.c_ispeed = termios_p->c_ispeed; -#endif -#if _HAVE_C_OSPEED && _HAVE_STRUCT_TERMIOS_C_OSPEED - k_termios.c_ospeed = termios_p->c_ospeed; -#endif - memcpy (&k_termios.c_cc[0], &termios_p->c_cc[0], - __KERNEL_NCCS * sizeof (cc_t)); + k_termios.c_line = termios_p->c_line; - return INLINE_SYSCALL (ioctl, 3, fd, cmd, &k_termios); + k_termios.c_ospeed = termios_p->c_ospeed; + k_termios.c_ispeed = termios_p->c_ispeed; + + ___termios2_canonicalize_speeds (&k_termios); + + copy_c_cc (k_termios.c_cc, _TERMIOS2_NCCS, termios_p->c_cc, NCCS); + + /* + * Choose the proper ioctl number to invoke. + * + * Alpha got TCSETS2 late (Linux 4.20), but has the same structure + * format, and it only needs TCSETS2 if either it needs to use + * __BOTHER or split speed. All other architectures have TCSETS2 as + * far back as the current glibc supports. Calling TCSETS with + * __BOTHER causes unpredictable results on old Alpha kernels and + * could even crash them. + */ + static_assert_equal(TCSADRAIN, TCSANOW + 1); + static_assert_equal(TCSAFLUSH, TCSANOW + 2); + static_assert_equal(TCSETSW2, TCSETS2 + 1); + static_assert_equal(TCSETSF2, TCSETS2 + 2); + static_assert_equal(TCSETSW, TCSETS + 1); + static_assert_equal(TCSETSF, TCSETS + 2); + + cmd = (long)optional_actions - TCSANOW; + if (cmd > 2) + return INLINE_SYSCALL_ERROR_RETURN_VALUE (EINVAL); + + if (__ASSUME_TERMIOS2 || + k_termios.c_ospeed != k_termios.c_ispeed || + cbaud (k_termios.c_cflag) == __BOTHER) + { + cmd += TCSETS2; + } + else + { + cmd += TCSETS; + k_termios.c_cflag &= ~CIBAUD; + } + + return INLINE_SYSCALL_CALL (ioctl, fd, cmd, &k_termios); } libc_hidden_def (__tcsetattr) + +#if _HAVE_STRUCT_OLD_TERMIOS && _TERMIOS_OLD_COMPAT + +versioned_symbol (libc, __tcsetattr, tcsetattr, GLIBC_2_42); + +/* Legacy version for shorter struct termios without speed fields */ +int +attribute_compat_text_section +__old_tcsetattr (int fd, int optional_actions, const old_termios_t *termios_p) +{ + struct termios new_termios; + + memset (&new_termios, 0, sizeof (new_termios)); + new_termios.c_iflag = termios_p->c_iflag; + new_termios.c_oflag = termios_p->c_oflag; + new_termios.c_cflag = termios_p->c_cflag; + new_termios.c_lflag = termios_p->c_lflag; + new_termios.c_line = termios_p->c_line; + copy_c_cc(new_termios.c_cc, NCCS, termios_p->c_cc, OLD_NCCS); + + return __tcsetattr (fd, optional_actions, &new_termios); +} +compat_symbol (libc, __old_tcsetattr, tcsetattr, GLIBC_2_0); + +#else + weak_alias (__tcsetattr, tcsetattr) + +#endif diff --git a/sysdeps/unix/sysv/linux/mips/kernel_termios.h b/sysdeps/unix/sysv/linux/termios_arch.h similarity index 50% rename from sysdeps/unix/sysv/linux/mips/kernel_termios.h rename to sysdeps/unix/sysv/linux/termios_arch.h index fd8d35a93e..8dbf420c28 100644 --- a/sysdeps/unix/sysv/linux/mips/kernel_termios.h +++ b/sysdeps/unix/sysv/linux/termios_arch.h @@ -1,4 +1,6 @@ -/* Copyright (C) 1997-2025 Free Software Foundation, Inc. +/* Architectural parameters for Linux termios - generic version + + Copyright (C) 1997-2025 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -12,26 +14,10 @@ Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library. If not, see + License along with the GNU C Library; if not, see . */ -#ifndef _KERNEL_TERMIOS_H -#define _KERNEL_TERMIOS_H 1 -/* The following corresponds to the values from the Linux 2.1.24 kernel. */ +#define _TERMIOS2_NCCS 19 +#define _HAVE_TERMIOS2_C_CC_BEFORE_C_LINE 0 -#define __KERNEL_NCCS 23 - -struct __kernel_termios - { - tcflag_t c_iflag; /* input mode flags */ - tcflag_t c_oflag; /* output mode flags */ - tcflag_t c_cflag; /* control mode flags */ - tcflag_t c_lflag; /* local mode flags */ - cc_t c_line; /* line discipline */ - cc_t c_cc[__KERNEL_NCCS]; /* control characters */ - }; - -#define _HAVE_C_ISPEED 0 -#define _HAVE_C_OSPEED 0 - -#endif /* kernel_termios.h */ +#define _HAVE_STRUCT_OLD_TERMIOS 0 diff --git a/sysdeps/unix/sysv/linux/termios_internals.h b/sysdeps/unix/sysv/linux/termios_internals.h new file mode 100644 index 0000000000..10b6732324 --- /dev/null +++ b/sysdeps/unix/sysv/linux/termios_internals.h @@ -0,0 +1,143 @@ +/* termios functions internal implementation header for Linux + + Copyright (C) 1991-2025 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#ifndef TERMIOS_INTERNALS_H +#define TERMIOS_INTERNALS_H 1 + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +/* ---- Kernel interface definitions ---- */ + +/* The the termios2 structure used in the kernel interfaces is not the + same as the termios structure we use in the libc. Therefore we + must translate it here. */ + +struct termios2 +{ + tcflag_t c_iflag; /* input mode flags */ + tcflag_t c_oflag; /* output mode flags */ + tcflag_t c_cflag; /* control mode flags */ + tcflag_t c_lflag; /* local mode flags */ +#if _HAVE_TERMIOS2_C_CC_BEFORE_C_LINE + cc_t c_cc[_TERMIOS2_NCCS]; /* control characters */ + cc_t c_line; /* line discipline */ +#else + cc_t c_line; /* line discipline */ + cc_t c_cc[_TERMIOS2_NCCS]; /* control characters */ +#endif + speed_t c_ispeed; /* input speed */ + speed_t c_ospeed; /* output speed */ +}; + +/* Alpha got termios2 late, but TCGETS has exactly the same structure + format and function as TCGETS2. On all other platforms, the termios2 + interface exists as far back as this version of glibc supports. + + For TCGETS* it is more complicated; this is handled in tcsetattr.c. + + Some other architectures only have the equivalent of the termios2 + interface, in which case the old ioctl names are the only ones + presented, but are equivalent to the new ones. */ +#ifndef TCGETS2 +# define TCGETS2 TCGETS +# define TCSETS2 TCSETS +# define TCSETSW2 TCSETSW +# define TCSETSF2 TCSETSF +#elif !__ASSUME_TERMIOS2 +/* Hack for Alpha */ +# undef TCGETS2 +# define TCGETS2 TCGETS +#endif + +/* ---- Application interface definitions ---- */ + +/* + * Should old speed_t and struct termios (if applicable) compatibility + * functions be included? + */ +#define _TERMIOS_OLD_COMPAT SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_42) + +/* + * Old struct termios (without c_ispeed and c_ospeed fields) if + * applicable. The new struct termios *must* be binary identical up to + * the sizeof the old structure. + * + * This only applies to SPARC and MIPS; for other architectures the + * new and old speed_t interfaces both use the same struct termios. + */ +#if _HAVE_STRUCT_OLD_TERMIOS +typedef struct old_termios old_termios_t; +#else +# define OLD_NCCS NCCS +typedef struct termios old_termios_t; +#endif + +/* ---- Internal function definitions ---- */ + +/* + * Copy a set of c_cc fields of possibly different width. If the target + * field is longer, then fill with _POSIX_VDISABLE == -1. + */ +static inline void +copy_c_cc (cc_t *to, size_t nto, const cc_t *from, size_t nfrom) +{ + if (nto < nfrom) + nfrom = nto; + + to = __mempcpy (to, from, nfrom * sizeof(cc_t)); + if (nto > nfrom) + memset (to, _POSIX_VDISABLE, (nto - nfrom) * sizeof(cc_t)); +} + +/* Extract the output and input legacy speed fields from c_cflag. */ +static inline tcflag_t +cbaud (tcflag_t c_cflag) +{ + return c_cflag & CBAUD; +} + +static inline tcflag_t +cibaud (tcflag_t c_cflag) +{ + return cbaud (c_cflag >> IBSHIFT); +} + +extern speed_t +___cbaud_to_speed (tcflag_t c_cflag, speed_t other) + __attribute_const__ attribute_hidden; + +extern tcflag_t +___speed_to_cbaud (speed_t speed) + __attribute_const__ attribute_hidden; + +extern void +___termios2_canonicalize_speeds (struct termios2 *k_termios_p) + attribute_hidden; + +#endif /* TERMIOS_INTERNALS_H */ diff --git a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist index 7ab9073e3a..ccf6ca2c88 100644 --- a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist +++ b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist @@ -2748,6 +2748,11 @@ GLIBC_2.41 sched_getattr F GLIBC_2.41 sched_setattr F GLIBC_2.42 __inet_ntop_chk F GLIBC_2.42 __inet_pton_chk F +GLIBC_2.42 cfgetispeed F +GLIBC_2.42 cfgetospeed F +GLIBC_2.42 cfsetispeed F +GLIBC_2.42 cfsetospeed F +GLIBC_2.42 cfsetspeed F GLIBC_2.42 pthread_gettid_np F GLIBC_2.42 uabs F GLIBC_2.42 uimaxabs F diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist index e11876f6ab..1e3e283954 100644 --- a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist +++ b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist @@ -2767,6 +2767,11 @@ GLIBC_2.41 sched_getattr F GLIBC_2.41 sched_setattr F GLIBC_2.42 __inet_ntop_chk F GLIBC_2.42 __inet_pton_chk F +GLIBC_2.42 cfgetispeed F +GLIBC_2.42 cfgetospeed F +GLIBC_2.42 cfsetispeed F +GLIBC_2.42 cfsetospeed F +GLIBC_2.42 cfsetspeed F GLIBC_2.42 pthread_gettid_np F GLIBC_2.42 uabs F GLIBC_2.42 uimaxabs F