[v4] linux/termio: remove <termio.h> and struct termio
Checks
| Context |
Check |
Description |
| redhat-pt-bot/TryBot-apply_patch |
success
|
Patch applied to master at the time it was sent
|
| redhat-pt-bot/TryBot-32bit |
success
|
Build for i686
|
| linaro-tcwg-bot/tcwg_glibc_build--master-arm |
success
|
Build passed
|
| linaro-tcwg-bot/tcwg_glibc_build--master-aarch64 |
success
|
Build passed
|
| linaro-tcwg-bot/tcwg_glibc_check--master-aarch64 |
success
|
Test passed
|
| linaro-tcwg-bot/tcwg_glibc_check--master-arm |
success
|
Test passed
|
Commit Message
The <termio.h> interface is absolutely ancient: it was obsoleted by
<termios.h> already in the first version of POSIX (1988) and thus
predates the very first version of Linux. Unfortunately, some constant
macros are used both by <termio.h> and <termios.h>; particularly
problematic is the baud rate constants since the termio interface
*requires* that the baud rate is set via an enumeration as part of
c_cflag.
In preparation of revamping the termios interface to support the
arbitrary baud rate capability that the Linux kernel has supported
since 2008, remove <termio.h> in the hope that no one still uses this
archaic interface.
Note that there is no actual code in glibc to support termio: it is
purely an unabstracted ioctl() interface.
[ v4: fix botched patch ]
[ v3: rebase onto current master ceeffd970c56893885cbf8382ae34b015f177850 ]
[ v2: remove separate struct termio definitions for mips and sparc ]
Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
---
NEWS | 5 +++++
sysdeps/unix/sysv/linux/Makefile | 6 ------
sysdeps/unix/sysv/linux/bits/ioctl-types.h | 11 -----------
sysdeps/unix/sysv/linux/mips/bits/ioctl-types.h | 12 ------------
sysdeps/unix/sysv/linux/powerpc/bits/ioctl-types.h | 11 -----------
sysdeps/unix/sysv/linux/termio.h | 6 ------
6 files changed, 5 insertions(+), 46 deletions(-)
delete mode 100644 sysdeps/unix/sysv/linux/termio.h
Comments
On 4/15/25 15:57, H. Peter Anvin wrote:
> The <termio.h> interface is absolutely ancient: it was obsoleted by
> <termios.h> already in the first version of POSIX (1988) and thus
> predates the very first version of Linux. Unfortunately, some constant
> macros are used both by <termio.h> and <termios.h>; particularly
> problematic is the baud rate constants since the termio interface
> *requires* that the baud rate is set via an enumeration as part of
> c_cflag.
>
> In preparation of revamping the termios interface to support the
> arbitrary baud rate capability that the Linux kernel has supported
> since 2008, remove <termio.h> in the hope that no one still uses this
> archaic interface.
>
> Note that there is no actual code in glibc to support termio: it is
> purely an unabstracted ioctl() interface.
>
> [ v4: fix botched patch ]
> [ v3: rebase onto current master ceeffd970c56893885cbf8382ae34b015f177850 ]
> [ v2: remove separate struct termio definitions for mips and sparc ]
Ping?
-hpa
* H. Peter Anvin:
> The <termio.h> interface is absolutely ancient: it was obsoleted by
> <termios.h> already in the first version of POSIX (1988) and thus
> predates the very first version of Linux. Unfortunately, some constant
> macros are used both by <termio.h> and <termios.h>; particularly
> problematic is the baud rate constants since the termio interface
> *requires* that the baud rate is set via an enumeration as part of
> c_cflag.
>
> In preparation of revamping the termios interface to support the
> arbitrary baud rate capability that the Linux kernel has supported
> since 2008, remove <termio.h> in the hope that no one still uses this
> archaic interface.
>
> Note that there is no actual code in glibc to support termio: it is
> purely an unabstracted ioctl() interface.
>
> [ v4: fix botched patch ]
> [ v3: rebase onto current master ceeffd970c56893885cbf8382ae34b015f177850 ]
> [ v2: remove separate struct termio definitions for mips and sparc ]
>
> Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
Reviewed-by: Florian Weimer <fweimer@redhat.com>
I'm going to apply this based on the previous discussion.
Thanks,
Florian
* H. Peter Anvin:
> The <termio.h> interface is absolutely ancient: it was obsoleted by
> <termios.h> already in the first version of POSIX (1988) and thus
> predates the very first version of Linux. Unfortunately, some constant
> macros are used both by <termio.h> and <termios.h>; particularly
> problematic is the baud rate constants since the termio interface
> *requires* that the baud rate is set via an enumeration as part of
> c_cflag.
>
> In preparation of revamping the termios interface to support the
> arbitrary baud rate capability that the Linux kernel has supported
> since 2008, remove <termio.h> in the hope that no one still uses this
> archaic interface.
>
> Note that there is no actual code in glibc to support termio: it is
> purely an unabstracted ioctl() interface.
>
> [ v4: fix botched patch ]
> [ v3: rebase onto current master ceeffd970c56893885cbf8382ae34b015f177850 ]
> [ v2: remove separate struct termio definitions for mips and sparc ]
>
> Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
> ---
> NEWS | 5 +++++
> sysdeps/unix/sysv/linux/Makefile | 6 ------
> sysdeps/unix/sysv/linux/bits/ioctl-types.h | 11 -----------
> sysdeps/unix/sysv/linux/mips/bits/ioctl-types.h | 12 ------------
> sysdeps/unix/sysv/linux/powerpc/bits/ioctl-types.h | 11 -----------
> sysdeps/unix/sysv/linux/termio.h | 6 ------
> 6 files changed, 5 insertions(+), 46 deletions(-)
> delete mode 100644 sysdeps/unix/sysv/linux/termio.h
I've pushed that. It's headed towards Fedora rawhide, so we'll see if
there's any breakage soon. Likewise for OpenSUSE tumbleweed.
Thanks,
Florian
On 4/25/25 08:44, Florian Weimer wrote:
> * H. Peter Anvin:
>
>> The <termio.h> interface is absolutely ancient: it was obsoleted by
>> <termios.h> already in the first version of POSIX (1988) and thus
>> predates the very first version of Linux. Unfortunately, some constant
>> macros are used both by <termio.h> and <termios.h>; particularly
>> problematic is the baud rate constants since the termio interface
>> *requires* that the baud rate is set via an enumeration as part of
>> c_cflag.
>>
>> In preparation of revamping the termios interface to support the
>> arbitrary baud rate capability that the Linux kernel has supported
>> since 2008, remove <termio.h> in the hope that no one still uses this
>> archaic interface.
>>
>> Note that there is no actual code in glibc to support termio: it is
>> purely an unabstracted ioctl() interface.
>>
>> [ v4: fix botched patch ]
>> [ v3: rebase onto current master ceeffd970c56893885cbf8382ae34b015f177850 ]
>> [ v2: remove separate struct termio definitions for mips and sparc ]
>>
>> Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
>> ---
>> NEWS | 5 +++++
>> sysdeps/unix/sysv/linux/Makefile | 6 ------
>> sysdeps/unix/sysv/linux/bits/ioctl-types.h | 11 -----------
>> sysdeps/unix/sysv/linux/mips/bits/ioctl-types.h | 12 ------------
>> sysdeps/unix/sysv/linux/powerpc/bits/ioctl-types.h | 11 -----------
>> sysdeps/unix/sysv/linux/termio.h | 6 ------
>> 6 files changed, 5 insertions(+), 46 deletions(-)
>> delete mode 100644 sysdeps/unix/sysv/linux/termio.h
>
> I've pushed that. It's headed towards Fedora rawhide, so we'll see if
> there's any breakage soon. Likewise for OpenSUSE tumbleweed.
>
So Linaro reports that this breaks gcc libsanitizer. This is simply
because of the following lines
sanitizer_common/sanitizer_platform_limits_posix.cpp [488-490]:
#if SANITIZER_GLIBC || SANITIZER_ANDROID
unsigned struct_termio_sz = sizeof(struct termio);
#endif
struct_termio_sz is then used in sanitizer_common_interceptors_ioctl.inc.
I see a few ways of fixing this:
1. In glibc: remove <termio.h> but leave the definition of struct termio
in <sys/ioctl.h>
2. Completely remove the above statement in gcc;
3. Do a weird hack in gcc hard-coding the size of legacy struct termio;
4. In gcc, get struct termio from <linux/termios.h> instead. This is
arguably More Correct anyway; libsanitizer is formally incorrect because
it gets the termios ioctls wrong (confusing glibc struct termios with
the kernel one.)
The real issue I guess is if we want to leave the struct termio in
sys/ioctl.h for the time being to avoid breaking the gcc build, or if we
want to push a patch into gcc and accept the breakage of libsanitizer in
the short term. I suspect the answer is no, and that we should thus fall
back on only removing <termio.h> for now.
* H. Peter Anvin:
> On 4/25/25 08:44, Florian Weimer wrote:
>> * H. Peter Anvin:
>>
>>> The <termio.h> interface is absolutely ancient: it was obsoleted by
>>> <termios.h> already in the first version of POSIX (1988) and thus
>>> predates the very first version of Linux. Unfortunately, some constant
>>> macros are used both by <termio.h> and <termios.h>; particularly
>>> problematic is the baud rate constants since the termio interface
>>> *requires* that the baud rate is set via an enumeration as part of
>>> c_cflag.
>>>
>>> In preparation of revamping the termios interface to support the
>>> arbitrary baud rate capability that the Linux kernel has supported
>>> since 2008, remove <termio.h> in the hope that no one still uses this
>>> archaic interface.
>>>
>>> Note that there is no actual code in glibc to support termio: it is
>>> purely an unabstracted ioctl() interface.
>>>
>>> [ v4: fix botched patch ]
>>> [ v3: rebase onto current master ceeffd970c56893885cbf8382ae34b015f177850 ]
>>> [ v2: remove separate struct termio definitions for mips and sparc ]
>>>
>>> Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
>>> ---
>>> NEWS | 5 +++++
>>> sysdeps/unix/sysv/linux/Makefile | 6 ------
>>> sysdeps/unix/sysv/linux/bits/ioctl-types.h | 11 -----------
>>> sysdeps/unix/sysv/linux/mips/bits/ioctl-types.h | 12 ------------
>>> sysdeps/unix/sysv/linux/powerpc/bits/ioctl-types.h | 11 -----------
>>> sysdeps/unix/sysv/linux/termio.h | 6 ------
>>> 6 files changed, 5 insertions(+), 46 deletions(-)
>>> delete mode 100644 sysdeps/unix/sysv/linux/termio.h
>>
>> I've pushed that. It's headed towards Fedora rawhide, so we'll see if
>> there's any breakage soon. Likewise for OpenSUSE tumbleweed.
>>
>
> So Linaro reports that this breaks gcc libsanitizer. This is simply
> because of the following lines
>
> sanitizer_common/sanitizer_platform_limits_posix.cpp [488-490]:
>
> #if SANITIZER_GLIBC || SANITIZER_ANDROID
> unsigned struct_termio_sz = sizeof(struct termio);
> #endif
>
> struct_termio_sz is then used in sanitizer_common_interceptors_ioctl.inc.
There's an upstream/LLVM PR for this:
[sanitizer_common] Remove interceptors for deprecated struct termio
<https://github.com/llvm/llvm-project/pull/137403>
I plan to submit a GCC patch once the LLVM change has been merged.
* Florian Weimer:
> * H. Peter Anvin:
>
>> On 4/25/25 08:44, Florian Weimer wrote:
>>> * H. Peter Anvin:
>>>
>>>> The <termio.h> interface is absolutely ancient: it was obsoleted by
>>>> <termios.h> already in the first version of POSIX (1988) and thus
>>>> predates the very first version of Linux. Unfortunately, some constant
>>>> macros are used both by <termio.h> and <termios.h>; particularly
>>>> problematic is the baud rate constants since the termio interface
>>>> *requires* that the baud rate is set via an enumeration as part of
>>>> c_cflag.
>>>>
>>>> In preparation of revamping the termios interface to support the
>>>> arbitrary baud rate capability that the Linux kernel has supported
>>>> since 2008, remove <termio.h> in the hope that no one still uses this
>>>> archaic interface.
>>>>
>>>> Note that there is no actual code in glibc to support termio: it is
>>>> purely an unabstracted ioctl() interface.
>>>>
>>>> [ v4: fix botched patch ]
>>>> [ v3: rebase onto current master ceeffd970c56893885cbf8382ae34b015f177850 ]
>>>> [ v2: remove separate struct termio definitions for mips and sparc ]
>>>>
>>>> Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
>>>> ---
>>>> NEWS | 5 +++++
>>>> sysdeps/unix/sysv/linux/Makefile | 6 ------
>>>> sysdeps/unix/sysv/linux/bits/ioctl-types.h | 11 -----------
>>>> sysdeps/unix/sysv/linux/mips/bits/ioctl-types.h | 12 ------------
>>>> sysdeps/unix/sysv/linux/powerpc/bits/ioctl-types.h | 11 -----------
>>>> sysdeps/unix/sysv/linux/termio.h | 6 ------
>>>> 6 files changed, 5 insertions(+), 46 deletions(-)
>>>> delete mode 100644 sysdeps/unix/sysv/linux/termio.h
>>>
>>> I've pushed that. It's headed towards Fedora rawhide, so we'll see if
>>> there's any breakage soon. Likewise for OpenSUSE tumbleweed.
>>>
>>
>> So Linaro reports that this breaks gcc libsanitizer. This is simply
>> because of the following lines
>>
>> sanitizer_common/sanitizer_platform_limits_posix.cpp [488-490]:
>>
>> #if SANITIZER_GLIBC || SANITIZER_ANDROID
>> unsigned struct_termio_sz = sizeof(struct termio);
>> #endif
>>
>> struct_termio_sz is then used in sanitizer_common_interceptors_ioctl.inc.
>
> There's an upstream/LLVM PR for this:
>
> [sanitizer_common] Remove interceptors for deprecated struct termio
> <https://github.com/llvm/llvm-project/pull/137403>
>
> I plan to submit a GCC patch once the LLVM change has been merged.
And Tom has a question:
> This isn't quite enough to fix the build. There are also uses of
> TCGETA, TCSETA, TCSETAF, and TCSETAW macros that reference struct
> termio. I'm not sure if these should be removed or if asm.h needs to
> be updated to use struct termios instead.
<https://github.com/llvm/llvm-project/pull/137403#issuecomment-2832595303>
I assume TCGETA etc. are only used with the legacy interface?
Peter, maybe you could comment on the PR?
On Apr 27 2025, Florian Weimer wrote:
> <https://github.com/llvm/llvm-project/pull/137403#issuecomment-2832595303>
>
> I assume TCGETA etc. are only used with the legacy interface?
It's still broken:
In file included from /usr/include/asm/ioctl.h:12,
from /usr/include/asm/ioctls.h:5,
from /usr/include/bits/ioctls.h:23,
from /usr/include/sys/ioctl.h:26,
from /usr/include/sys/mount.h:28,
from ../../../../libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.cpp:64:
../../../../libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.cpp:765:27: error: invalid application of ‘sizeof’ to incomplete type ‘__sanitizer::termio’
765 | unsigned IOCTL_TCGETA = TCGETA;
| ^~~~~~
../../../../libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.cpp:769:27: error: invalid application of ‘sizeof’ to incomplete type ‘__sanitizer::termio’
769 | unsigned IOCTL_TCSETA = TCSETA;
| ^~~~~~
../../../../libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.cpp:770:28: error: invalid application of ‘sizeof’ to incomplete type ‘__sanitizer::termio’
770 | unsigned IOCTL_TCSETAF = TCSETAF;
| ^~~~~~~
../../../../libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.cpp:771:28: error: invalid application of ‘sizeof’ to incomplete type ‘__sanitizer::termio’
771 | unsigned IOCTL_TCSETAW = TCSETAW;
| ^~~~~~~
make[4]: *** [Makefile:627: sanitizer_platform_limits_posix.lo] Error 1
make[4]: Leaving directory '/home/abuild/rpmbuild/BUILD/gcc16-testresults-16.0.0+git433-build/gcc-16.0.0+git433/obj-powerpc64le-suse-linux/powerpc64le-suse-linux/libsanitizer/sanitizer_common'
This is https://github.com/llvm/llvm-project/pull/138822 now.
On May 7, 2025 1:01:40 AM PDT, Andreas Schwab <schwab@suse.de> wrote:
>On Apr 27 2025, Florian Weimer wrote:
>
>> <https://github.com/llvm/llvm-project/pull/137403#issuecomment-2832595303>
>>
>> I assume TCGETA etc. are only used with the legacy interface?
>
>It's still broken:
>
>In file included from /usr/include/asm/ioctl.h:12,
> from /usr/include/asm/ioctls.h:5,
> from /usr/include/bits/ioctls.h:23,
> from /usr/include/sys/ioctl.h:26,
> from /usr/include/sys/mount.h:28,
> from ../../../../libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.cpp:64:
>../../../../libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.cpp:765:27: error: invalid application of ‘sizeof’ to incomplete type ‘__sanitizer::termio’
> 765 | unsigned IOCTL_TCGETA = TCGETA;
> | ^~~~~~
>../../../../libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.cpp:769:27: error: invalid application of ‘sizeof’ to incomplete type ‘__sanitizer::termio’
> 769 | unsigned IOCTL_TCSETA = TCSETA;
> | ^~~~~~
>../../../../libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.cpp:770:28: error: invalid application of ‘sizeof’ to incomplete type ‘__sanitizer::termio’
> 770 | unsigned IOCTL_TCSETAF = TCSETAF;
> | ^~~~~~~
>../../../../libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.cpp:771:28: error: invalid application of ‘sizeof’ to incomplete type ‘__sanitizer::termio’
> 771 | unsigned IOCTL_TCSETAW = TCSETAW;
> | ^~~~~~~
>make[4]: *** [Makefile:627: sanitizer_platform_limits_posix.lo] Error 1
>make[4]: Leaving directory '/home/abuild/rpmbuild/BUILD/gcc16-testresults-16.0.0+git433-build/gcc-16.0.0+git433/obj-powerpc64le-suse-linux/powerpc64le-suse-linux/libsanitizer/sanitizer_common'
>
Yes, I believe my comment on the bug report is the right way to fix it.
ioctl is a kernel interface, and the types should be picked up from the kernel headers.
On 5/7/25 01:24, Andreas Schwab wrote:
> This is https://github.com/llvm/llvm-project/pull/138822 now.
I don't have any direct objection, but please see my note:
https://github.com/llvm/llvm-project/issues/137321#issuecomment-2836993353
@@ -27,6 +27,11 @@ Deprecated and removed features, and other changes affecting compatibility:
programs that require an executable stack through dynamic loaded
shared libraries.
+* On Linux, the <termio.h> header and the definition of struct termio
+ in <sys/ioctl.h> have been removed. The termio interface has been
+ obsolete since the very first version of POSIX.1 in 1988, replaced
+ with <termios.h>.
+
Changes to build and runtime requirements:
* GCC 12.1 or later is now required to build the GNU C Library.
@@ -506,12 +506,6 @@ sysdep_headers += \
# sysdep_headers
endif
-ifeq ($(subdir),termios)
-sysdep_headers += \
- termio.h \
- # sysdep_headers
-endif
-
ifeq ($(subdir),posix)
sysdep_headers += \
bits/initspin.h \
@@ -32,17 +32,6 @@ struct winsize
unsigned short int ws_ypixel;
};
-#define NCC 8
-struct termio
- {
- unsigned short int c_iflag; /* input mode flags */
- unsigned short int c_oflag; /* output mode flags */
- unsigned short int c_cflag; /* control mode flags */
- unsigned short int c_lflag; /* local mode flags */
- unsigned char c_line; /* line discipline */
- unsigned char c_cc[NCC]; /* control characters */
-};
-
/* modem lines */
#define TIOCM_LE 0x001
#define TIOCM_DTR 0x002
@@ -31,18 +31,6 @@ struct winsize
unsigned short int ws_ypixel;
};
-#define NCC 8
-struct termio
- {
- unsigned short int c_iflag; /* input mode flags */
- unsigned short int c_oflag; /* output mode flags */
- unsigned short int c_cflag; /* control mode flags */
- unsigned short int c_lflag; /* local mode flags */
- char c_line; /* line discipline */
- /* Yes, this is really NCCS. */
- unsigned char c_cc[32 /* NCCS */]; /* control characters */
- };
-
/* modem lines */
#define TIOCM_LE 0x001 /* line enable */
#define TIOCM_DTR 0x002 /* data terminal ready */
@@ -32,17 +32,6 @@ struct winsize
unsigned short int ws_ypixel;
};
-#define NCC 10
-struct termio
- {
- unsigned short int c_iflag; /* input mode flags */
- unsigned short int c_oflag; /* output mode flags */
- unsigned short int c_cflag; /* control mode flags */
- unsigned short int c_lflag; /* local mode flags */
- unsigned char c_line; /* line discipline */
- unsigned char c_cc[NCC]; /* control characters */
-};
-
/* modem lines */
#define TIOCM_LE 0x001
#define TIOCM_DTR 0x002
deleted file mode 100644
@@ -1,6 +0,0 @@
-/* Compatible <termio.h> for old `struct termio' ioctl interface.
- This is obsolete; use the POSIX.1 `struct termios' interface
- defined in <termios.h> instead. */
-
-#include <termios.h>
-#include <sys/ioctl.h>