[02/12] termios: Consolidate struct termios

Message ID 20181015204956.25558-2-adhemerval.zanella@linaro.org
State Dropped
Headers

Commit Message

Adhemerval Zanella Oct. 15, 2018, 8:49 p.m. UTC
  This patch consolidates the struct termios definition on its own header
and adds arch-defined ones for ABIs that deviate from generic
implementation. They are:

  - alpha which has a slight different layout than generic one (c_cc
    field is defined prior c_line).

  - sparc and mips which do not have the c_ispeed/c_ospeed fields.

No semantic change is expected, checked on a build against x86_64-linux-gnu,
alpha-linux-gnu, mips64-linux-gnu, and sparc64-linux-gnu.

	* sysdeps/unix/sysv/linux/alpha/bits/termios-struct.h: New file.
	* sysdeps/unix/sysv/linux/bits/termios-struct.h: Likewise.
	* sysdeps/unix/sysv/linux/mips/bits/termios-struct.h: Likewise.
	* sysdeps/unix/sysv/linux/sparc/bits/termios-struct.h: Likewise.
	* sysdeps/unix/sysv/linux/Makefile (sysdep_headers): Add
	termios-struct.h.
	* sysdeps/unix/sysv/linux/bits/termios.h (struct termios): Move to
	termios-struct.h.
	* sysdeps/unix/sysv/linux/alpha/bits/termios.h (struct termios):
	Likewise.
	* sysdeps/unix/sysv/linux/mips/bits/termios.h (struct termios):
	Likewise.
	* sysdeps/unix/sysv/linux/powerpc/bits/termios.h (struct termios):
	Likewise.
	* sysdeps/unix/sysv/linux/sparc/bits/termios.h (struct termios):
	Likewise.
	* sysdeps/unix/sysv/linux/kernel_termios.h (_HAVE_C_ISPEED,
	_HAVE_C_OSPEED): Define.
	* sysdeps/unix/sysv/linux/mips/kernel_termios.h (_HAVE_C_ISPEED,
	_HAVE_C_OSPEED): Likewise.
	* sysdeps/unix/sysv/linux/sparc/kernel_termios.h (_HAVE_C_ISPEED,
	_HAVE_C_OSPEED): Likewise.
	* sysdeps/unix/sysv/linux/speed.c [_HAVE_STRUCT_TERMIOS_C_OSPEED]
	(cfsetospeed): Check for define value instead of existence.
	[_HAVE_STRUCT_TERMIOS_C_ISPEED] (cfsetispeed): Likewise.
	* sysdeps/unix/sysv/linux/tcgetattr.c [_HAVE_STRUCT_TERMIOS_C_ISPEED
	&& _HAVE_C_ISPEED] (__tcgetattr): Likewise.
	* sysdeps/unix/sysv/linux/tcsetattr.c [_HAVE_STRUCT_TERMIOS_C_ISPEED
	&& _HAVE_C_ISPEED] (__tcsetattr): Likewise.
---
 sysdeps/unix/sysv/linux/Makefile              |  2 +-
 .../sysv/linux/alpha/bits/termios-struct.h    | 37 +++++++++++++++++++
 sysdeps/unix/sysv/linux/alpha/bits/termios.h  | 15 +-------
 sysdeps/unix/sysv/linux/bits/termios-struct.h | 36 ++++++++++++++++++
 sysdeps/unix/sysv/linux/bits/termios.h        | 15 +-------
 sysdeps/unix/sysv/linux/kernel_termios.h      |  3 ++
 .../sysv/linux/mips/bits/termios-struct.h     | 34 +++++++++++++++++
 sysdeps/unix/sysv/linux/mips/bits/termios.h   | 11 +-----
 sysdeps/unix/sysv/linux/mips/kernel_termios.h |  3 ++
 .../unix/sysv/linux/powerpc/bits/termios.h    | 20 +---------
 .../sysv/linux/sparc/bits/termios-struct.h    | 34 +++++++++++++++++
 sysdeps/unix/sysv/linux/sparc/bits/termios.h  | 11 +-----
 .../unix/sysv/linux/sparc/kernel_termios.h    |  3 ++
 sysdeps/unix/sysv/linux/speed.c               |  4 +-
 sysdeps/unix/sysv/linux/tcgetattr.c           |  8 ++--
 sysdeps/unix/sysv/linux/tcsetattr.c           |  4 +-
 16 files changed, 164 insertions(+), 76 deletions(-)
 create mode 100644 sysdeps/unix/sysv/linux/alpha/bits/termios-struct.h
 create mode 100644 sysdeps/unix/sysv/linux/bits/termios-struct.h
 create mode 100644 sysdeps/unix/sysv/linux/mips/bits/termios-struct.h
 create mode 100644 sysdeps/unix/sysv/linux/sparc/bits/termios-struct.h
  

Comments

Adhemerval Zanella Nov. 6, 2018, 5:14 p.m. UTC | #1
Ping.


On 15/10/2018 17:49, Adhemerval Zanella wrote:
> This patch consolidates the struct termios definition on its own header
> and adds arch-defined ones for ABIs that deviate from generic
> implementation. They are:
> 
>   - alpha which has a slight different layout than generic one (c_cc
>     field is defined prior c_line).
> 
>   - sparc and mips which do not have the c_ispeed/c_ospeed fields.
> 
> No semantic change is expected, checked on a build against x86_64-linux-gnu,
> alpha-linux-gnu, mips64-linux-gnu, and sparc64-linux-gnu.
> 
> 	* sysdeps/unix/sysv/linux/alpha/bits/termios-struct.h: New file.
> 	* sysdeps/unix/sysv/linux/bits/termios-struct.h: Likewise.
> 	* sysdeps/unix/sysv/linux/mips/bits/termios-struct.h: Likewise.
> 	* sysdeps/unix/sysv/linux/sparc/bits/termios-struct.h: Likewise.
> 	* sysdeps/unix/sysv/linux/Makefile (sysdep_headers): Add
> 	termios-struct.h.
> 	* sysdeps/unix/sysv/linux/bits/termios.h (struct termios): Move to
> 	termios-struct.h.
> 	* sysdeps/unix/sysv/linux/alpha/bits/termios.h (struct termios):
> 	Likewise.
> 	* sysdeps/unix/sysv/linux/mips/bits/termios.h (struct termios):
> 	Likewise.
> 	* sysdeps/unix/sysv/linux/powerpc/bits/termios.h (struct termios):
> 	Likewise.
> 	* sysdeps/unix/sysv/linux/sparc/bits/termios.h (struct termios):
> 	Likewise.
> 	* sysdeps/unix/sysv/linux/kernel_termios.h (_HAVE_C_ISPEED,
> 	_HAVE_C_OSPEED): Define.
> 	* sysdeps/unix/sysv/linux/mips/kernel_termios.h (_HAVE_C_ISPEED,
> 	_HAVE_C_OSPEED): Likewise.
> 	* sysdeps/unix/sysv/linux/sparc/kernel_termios.h (_HAVE_C_ISPEED,
> 	_HAVE_C_OSPEED): Likewise.
> 	* sysdeps/unix/sysv/linux/speed.c [_HAVE_STRUCT_TERMIOS_C_OSPEED]
> 	(cfsetospeed): Check for define value instead of existence.
> 	[_HAVE_STRUCT_TERMIOS_C_ISPEED] (cfsetispeed): Likewise.
> 	* sysdeps/unix/sysv/linux/tcgetattr.c [_HAVE_STRUCT_TERMIOS_C_ISPEED
> 	&& _HAVE_C_ISPEED] (__tcgetattr): Likewise.
> 	* sysdeps/unix/sysv/linux/tcsetattr.c [_HAVE_STRUCT_TERMIOS_C_ISPEED
> 	&& _HAVE_C_ISPEED] (__tcsetattr): Likewise.
> ---
>  sysdeps/unix/sysv/linux/Makefile              |  2 +-
>  .../sysv/linux/alpha/bits/termios-struct.h    | 37 +++++++++++++++++++
>  sysdeps/unix/sysv/linux/alpha/bits/termios.h  | 15 +-------
>  sysdeps/unix/sysv/linux/bits/termios-struct.h | 36 ++++++++++++++++++
>  sysdeps/unix/sysv/linux/bits/termios.h        | 15 +-------
>  sysdeps/unix/sysv/linux/kernel_termios.h      |  3 ++
>  .../sysv/linux/mips/bits/termios-struct.h     | 34 +++++++++++++++++
>  sysdeps/unix/sysv/linux/mips/bits/termios.h   | 11 +-----
>  sysdeps/unix/sysv/linux/mips/kernel_termios.h |  3 ++
>  .../unix/sysv/linux/powerpc/bits/termios.h    | 20 +---------
>  .../sysv/linux/sparc/bits/termios-struct.h    | 34 +++++++++++++++++
>  sysdeps/unix/sysv/linux/sparc/bits/termios.h  | 11 +-----
>  .../unix/sysv/linux/sparc/kernel_termios.h    |  3 ++
>  sysdeps/unix/sysv/linux/speed.c               |  4 +-
>  sysdeps/unix/sysv/linux/tcgetattr.c           |  8 ++--
>  sysdeps/unix/sysv/linux/tcsetattr.c           |  4 +-
>  16 files changed, 164 insertions(+), 76 deletions(-)
>  create mode 100644 sysdeps/unix/sysv/linux/alpha/bits/termios-struct.h
>  create mode 100644 sysdeps/unix/sysv/linux/bits/termios-struct.h
>  create mode 100644 sysdeps/unix/sysv/linux/mips/bits/termios-struct.h
>  create mode 100644 sysdeps/unix/sysv/linux/sparc/bits/termios-struct.h
> 
> diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile
> index ff4535cdca..184a5b19e1 100644
> --- a/sysdeps/unix/sysv/linux/Makefile
> +++ b/sysdeps/unix/sysv/linux/Makefile
> @@ -43,7 +43,7 @@ sysdep_headers += sys/mount.h sys/acct.h sys/sysctl.h \
>  		  bits/siginfo-arch.h bits/siginfo-consts-arch.h \
>  		  bits/procfs.h bits/procfs-id.h bits/procfs-extra.h \
>  		  bits/procfs-prregset.h bits/mman-map-flags-generic.h \
> -		  bits/msq-pad.h
> +		  bits/msq-pad.h bits/termios-struct.h
>  
>  tests += tst-clone tst-clone2 tst-clone3 tst-fanotify tst-personality \
>  	 tst-quota tst-sync_file_range tst-sysconf-iov_max tst-ttyname \
> diff --git a/sysdeps/unix/sysv/linux/alpha/bits/termios-struct.h b/sysdeps/unix/sysv/linux/alpha/bits/termios-struct.h
> new file mode 100644
> index 0000000000..268988c1a4
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/alpha/bits/termios-struct.h
> @@ -0,0 +1,37 @@
> +/* struct termios definition.  Linux/alpha version.
> +   Copyright (C) 2018 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
> +   <http://www.gnu.org/licenses/>.  */
> +
> +#ifndef _TERMIOS_H
> +# error "Never include <bits/termios-struct.h> directly; use <termios.h> instead."
> +#endif
> +
> +/* Alpha has C_CC before C_LINE compare to Linux generic definition.  */
> +#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_cc[NCCS];		/* control characters */
> +    cc_t c_line;		/* line discipline (== c_cc[33]) */
> +    speed_t c_ispeed;		/* input speed */
> +    speed_t c_ospeed;		/* output speed */
> +#define _HAVE_STRUCT_TERMIOS_C_ISPEED 1
> +#define _HAVE_STRUCT_TERMIOS_C_OSPEED 1
> +  };
> diff --git a/sysdeps/unix/sysv/linux/alpha/bits/termios.h b/sysdeps/unix/sysv/linux/alpha/bits/termios.h
> index 24423e8fc9..fe358dd8f5 100644
> --- a/sysdeps/unix/sysv/linux/alpha/bits/termios.h
> +++ b/sysdeps/unix/sysv/linux/alpha/bits/termios.h
> @@ -24,20 +24,7 @@ typedef unsigned char	cc_t;
>  typedef unsigned int	speed_t;
>  typedef unsigned int	tcflag_t;
>  
> -#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_cc[NCCS];		/* control characters */
> -    cc_t c_line;		/* line discipline (== c_cc[33]) */
> -    speed_t c_ispeed;		/* input speed */
> -    speed_t c_ospeed;		/* output speed */
> -#define _HAVE_STRUCT_TERMIOS_C_ISPEED 1
> -#define _HAVE_STRUCT_TERMIOS_C_OSPEED 1
> -  };
> +#include <bits/termios-struct.h>
>  
>  /* c_cc characters */
>  #define VEOF 0
> diff --git a/sysdeps/unix/sysv/linux/bits/termios-struct.h b/sysdeps/unix/sysv/linux/bits/termios-struct.h
> new file mode 100644
> index 0000000000..ba56a547c1
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/bits/termios-struct.h
> @@ -0,0 +1,36 @@
> +/* struct termios definition.  Linux/generic version.
> +   Copyright (C) 2018 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
> +   <http://www.gnu.org/licenses/>.  */
> +
> +#ifndef _TERMIOS_H
> +# error "Never include <bits/termios-struct.h> directly; use <termios.h> instead."
> +#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 */
> +    speed_t c_ispeed;		/* input speed */
> +    speed_t c_ospeed;		/* output speed */
> +#define _HAVE_STRUCT_TERMIOS_C_ISPEED 1
> +#define _HAVE_STRUCT_TERMIOS_C_OSPEED 1
> +  };
> diff --git a/sysdeps/unix/sysv/linux/bits/termios.h b/sysdeps/unix/sysv/linux/bits/termios.h
> index 1e567affc3..93536130aa 100644
> --- a/sysdeps/unix/sysv/linux/bits/termios.h
> +++ b/sysdeps/unix/sysv/linux/bits/termios.h
> @@ -24,20 +24,7 @@ typedef unsigned char	cc_t;
>  typedef unsigned int	speed_t;
>  typedef unsigned int	tcflag_t;
>  
> -#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 */
> -    speed_t c_ispeed;		/* input speed */
> -    speed_t c_ospeed;		/* output speed */
> -#define _HAVE_STRUCT_TERMIOS_C_ISPEED 1
> -#define _HAVE_STRUCT_TERMIOS_C_OSPEED 1
> -  };
> +#include <bits/termios-struct.h>
>  
>  /* c_cc characters */
>  #define VINTR 0
> diff --git a/sysdeps/unix/sysv/linux/kernel_termios.h b/sysdeps/unix/sysv/linux/kernel_termios.h
> index 6f505c7b61..cd000af833 100644
> --- a/sysdeps/unix/sysv/linux/kernel_termios.h
> +++ b/sysdeps/unix/sysv/linux/kernel_termios.h
> @@ -31,4 +31,7 @@ struct __kernel_termios
>      cc_t c_cc[__KERNEL_NCCS];	/* control characters */
>    };
>  
> +#define _HAVE_C_ISPEED 0
> +#define _HAVE_C_OSPEED 0
> +
>  #endif /* kernel_termios.h */
> diff --git a/sysdeps/unix/sysv/linux/mips/bits/termios-struct.h b/sysdeps/unix/sysv/linux/mips/bits/termios-struct.h
> new file mode 100644
> index 0000000000..f7684e51f1
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/mips/bits/termios-struct.h
> @@ -0,0 +1,34 @@
> +/* struct termios definition.  Linux/mips version.
> +   Copyright (C) 2018 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
> +   <http://www.gnu.org/licenses/>.  */
> +
> +#ifndef _TERMIOS_H
> +# error "Never include <bits/termios-struct.h> directly; use <termios.h> instead."
> +#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
> +  };
> diff --git a/sysdeps/unix/sysv/linux/mips/bits/termios.h b/sysdeps/unix/sysv/linux/mips/bits/termios.h
> index 7969144633..2b2f873f35 100644
> --- a/sysdeps/unix/sysv/linux/mips/bits/termios.h
> +++ b/sysdeps/unix/sysv/linux/mips/bits/termios.h
> @@ -24,16 +24,7 @@ typedef unsigned char	cc_t;
>  typedef unsigned int	speed_t;
>  typedef unsigned int	tcflag_t;
>  
> -#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 */
> -  };
> +#include <bits/termios-struct.h>
>  
>  /* c_cc characters */
>  #define VINTR		0	/* Interrupt character [ISIG].  */
> diff --git a/sysdeps/unix/sysv/linux/mips/kernel_termios.h b/sysdeps/unix/sysv/linux/mips/kernel_termios.h
> index 1c54b19428..5f88c745a0 100644
> --- a/sysdeps/unix/sysv/linux/mips/kernel_termios.h
> +++ b/sysdeps/unix/sysv/linux/mips/kernel_termios.h
> @@ -31,4 +31,7 @@ struct __kernel_termios
>      cc_t c_cc[__KERNEL_NCCS];	/* control characters */
>    };
>  
> +#define _HAVE_C_ISPEED 0
> +#define _HAVE_C_OSPEED 0
> +
>  #endif /* kernel_termios.h */
> diff --git a/sysdeps/unix/sysv/linux/powerpc/bits/termios.h b/sysdeps/unix/sysv/linux/powerpc/bits/termios.h
> index afe592d5e4..ddb32bd7e5 100644
> --- a/sysdeps/unix/sysv/linux/powerpc/bits/termios.h
> +++ b/sysdeps/unix/sysv/linux/powerpc/bits/termios.h
> @@ -23,25 +23,7 @@ typedef unsigned char	cc_t;
>  typedef unsigned int	speed_t;
>  typedef unsigned int	tcflag_t;
>  
> -/*
> - * termios type and macro definitions.  Be careful about adding stuff
> - * to this file since it's used in GNU libc and there are strict rules
> - * concerning namespace pollution.
> - */
> -
> -#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 (== c_cc[19]) */
> -	cc_t c_cc[NCCS];		/* control characters */
> -	speed_t c_ispeed;		/* input speed */
> -	speed_t c_ospeed;		/* output speed */
> -#define _HAVE_STRUCT_TERMIOS_C_ISPEED 1
> -#define _HAVE_STRUCT_TERMIOS_C_OSPEED 1
> -};
> +#include <bits/termios-struct.h>
>  
>  /* c_cc characters */
>  #define VINTR	0
> diff --git a/sysdeps/unix/sysv/linux/sparc/bits/termios-struct.h b/sysdeps/unix/sysv/linux/sparc/bits/termios-struct.h
> new file mode 100644
> index 0000000000..7c3489e1b9
> --- /dev/null
> +++ b/sysdeps/unix/sysv/linux/sparc/bits/termios-struct.h
> @@ -0,0 +1,34 @@
> +/* struct termios definition.  Linux/sparc version.
> +   Copyright (C) 2018 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
> +   <http://www.gnu.org/licenses/>.  */
> +
> +#ifndef _TERMIOS_H
> +# error "Never include <bits/termios-struct.h> directly; use <termios.h> instead."
> +#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
> +  };
> diff --git a/sysdeps/unix/sysv/linux/sparc/bits/termios.h b/sysdeps/unix/sysv/linux/sparc/bits/termios.h
> index ffe8483694..5fd6055c8e 100644
> --- a/sysdeps/unix/sysv/linux/sparc/bits/termios.h
> +++ b/sysdeps/unix/sysv/linux/sparc/bits/termios.h
> @@ -24,16 +24,7 @@ typedef unsigned char cc_t;
>  typedef unsigned int speed_t;
>  typedef unsigned int tcflag_t;
>  
> -#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 */
> -  };
> +#include <bits/termios-struct.h>
>  
>  /* c_cc characters */
>  #define VINTR    0
> diff --git a/sysdeps/unix/sysv/linux/sparc/kernel_termios.h b/sysdeps/unix/sysv/linux/sparc/kernel_termios.h
> index 31c717ea9d..3a27382d36 100644
> --- a/sysdeps/unix/sysv/linux/sparc/kernel_termios.h
> +++ b/sysdeps/unix/sysv/linux/sparc/kernel_termios.h
> @@ -34,4 +34,7 @@ struct __kernel_termios
>      cc_t c_cc[__KERNEL_NCCS];	/* control characters */
>    };
>  
> +#define _HAVE_C_ISPEED 0
> +#define _HAVE_C_OSPEED 0
> +
>  #endif /* kernel_termios.h */
> diff --git a/sysdeps/unix/sysv/linux/speed.c b/sysdeps/unix/sysv/linux/speed.c
> index 7db9e998c3..23834c10b5 100644
> --- a/sysdeps/unix/sysv/linux/speed.c
> +++ b/sysdeps/unix/sysv/linux/speed.c
> @@ -58,7 +58,7 @@ cfsetospeed (struct termios *termios_p, speed_t speed)
>        && (speed < B57600 || speed > __MAX_BAUD))
>      return INLINE_SYSCALL_ERROR_RETURN_VALUE (EINVAL);
>  
> -#ifdef _HAVE_STRUCT_TERMIOS_C_OSPEED
> +#if _HAVE_STRUCT_TERMIOS_C_OSPEED
>    termios_p->c_ospeed = speed;
>  #endif
>    termios_p->c_cflag &= ~(CBAUD | CBAUDEX);
> @@ -80,7 +80,7 @@ cfsetispeed (struct termios *termios_p, speed_t speed)
>        && (speed < B57600 || speed > __MAX_BAUD))
>      return INLINE_SYSCALL_ERROR_RETURN_VALUE (EINVAL);
>  
> -#ifdef _HAVE_STRUCT_TERMIOS_C_ISPEED
> +#if _HAVE_STRUCT_TERMIOS_C_ISPEED
>    termios_p->c_ispeed = speed;
>  #endif
>    if (speed == 0)
> diff --git a/sysdeps/unix/sysv/linux/tcgetattr.c b/sysdeps/unix/sysv/linux/tcgetattr.c
> index 9748bc8cc4..b79d9f1462 100644
> --- a/sysdeps/unix/sysv/linux/tcgetattr.c
> +++ b/sysdeps/unix/sysv/linux/tcgetattr.c
> @@ -44,15 +44,15 @@ __tcgetattr (int fd, struct termios *termios_p)
>        termios_p->c_cflag = k_termios.c_cflag;
>        termios_p->c_lflag = k_termios.c_lflag;
>        termios_p->c_line = k_termios.c_line;
> -#ifdef _HAVE_STRUCT_TERMIOS_C_ISPEED
> -# ifdef _HAVE_C_ISPEED
> +#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
> -#ifdef _HAVE_STRUCT_TERMIOS_C_OSPEED
> -# ifdef _HAVE_C_OSPEED
> +#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);
> diff --git a/sysdeps/unix/sysv/linux/tcsetattr.c b/sysdeps/unix/sysv/linux/tcsetattr.c
> index a916e70253..f8025a0473 100644
> --- a/sysdeps/unix/sysv/linux/tcsetattr.c
> +++ b/sysdeps/unix/sysv/linux/tcsetattr.c
> @@ -66,10 +66,10 @@ __tcsetattr (int fd, int optional_actions, const struct termios *termios_p)
>    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 defined _HAVE_C_ISPEED && defined _HAVE_STRUCT_TERMIOS_C_ISPEED
> +#if _HAVE_C_ISPEED && _HAVE_STRUCT_TERMIOS_C_ISPEED
>    k_termios.c_ispeed = termios_p->c_ispeed;
>  #endif
> -#if defined _HAVE_C_OSPEED && defined _HAVE_STRUCT_TERMIOS_C_OSPEED
> +#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],
>
  
Gabriel F. T. Gomes Nov. 9, 2018, 1:43 p.m. UTC | #2
Hi, Adhemerval.  Could you help me with a doubt (below)?

On Mon, 15 Oct 2018, Adhemerval Zanella wrote:

>--- /dev/null
>+++ b/sysdeps/unix/sysv/linux/bits/termios-struct.h
> [...]
>+#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 */
>+    speed_t c_ispeed;		/* input speed */
>+    speed_t c_ospeed;		/* output speed */
>+#define _HAVE_STRUCT_TERMIOS_C_ISPEED 1
>+#define _HAVE_STRUCT_TERMIOS_C_OSPEED 1
>+  };

The generic header will have c_line before c_cc.

>--- a/sysdeps/unix/sysv/linux/powerpc/bits/termios.h
>+++ b/sysdeps/unix/sysv/linux/powerpc/bits/termios.h
> [...]
>-#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 (== c_cc[19]) */
>-	cc_t c_cc[NCCS];		/* control characters */
>-	speed_t c_ispeed;		/* input speed */
>-	speed_t c_ospeed;		/* output speed */
>-#define _HAVE_STRUCT_TERMIOS_C_ISPEED 1
>-#define _HAVE_STRUCT_TERMIOS_C_OSPEED 1
>-};
>+#include <bits/termios-struct.h>

So does the powerpc-specific header.

As far as I can tell, your patch is doing the right thing, because it's
not modifying what we currently have in glibc.

On the other hand, I just checked the source code for Linux [1] and these
two lines are flipped.  This inconsistency between kernel and glibc looks
weird...  Is this a bug in current glibc?

[1] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/arch/powerpc/include/uapi/asm/termbits.h#n16
  
Adhemerval Zanella Nov. 9, 2018, 5:07 p.m. UTC | #3
On 09/11/2018 11:43, Gabriel F. T. Gomes wrote:
> Hi, Adhemerval.  Could you help me with a doubt (below)?
> 
> On Mon, 15 Oct 2018, Adhemerval Zanella wrote:
> 
>> --- /dev/null
>> +++ b/sysdeps/unix/sysv/linux/bits/termios-struct.h
>> [...]
>> +#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 */
>> +    speed_t c_ispeed;		/* input speed */
>> +    speed_t c_ospeed;		/* output speed */
>> +#define _HAVE_STRUCT_TERMIOS_C_ISPEED 1
>> +#define _HAVE_STRUCT_TERMIOS_C_OSPEED 1
>> +  };
> 
> The generic header will have c_line before c_cc.
> 
>> --- a/sysdeps/unix/sysv/linux/powerpc/bits/termios.h
>> +++ b/sysdeps/unix/sysv/linux/powerpc/bits/termios.h
>> [...]
>> -#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 (== c_cc[19]) */
>> -	cc_t c_cc[NCCS];		/* control characters */
>> -	speed_t c_ispeed;		/* input speed */
>> -	speed_t c_ospeed;		/* output speed */
>> -#define _HAVE_STRUCT_TERMIOS_C_ISPEED 1
>> -#define _HAVE_STRUCT_TERMIOS_C_OSPEED 1
>> -};
>> +#include <bits/termios-struct.h>
> 
> So does the powerpc-specific header.
> 
> As far as I can tell, your patch is doing the right thing, because it's
> not modifying what we currently have in glibc.
> 
> On the other hand, I just checked the source code for Linux [1] and these
> two lines are flipped.  This inconsistency between kernel and glibc looks
> weird...  Is this a bug in current glibc?
> 
> [1] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/arch/powerpc/include/uapi/asm/termbits.h#n16
> 

For termios we do not follow kernel userspace ABI, glibc defines both
input and output speed in termios structure and it differs from termios
kernel generic abi (include/uapi/asm-generic/termios.h).  In fact glibc
follows the termios2 struct definition for most architectures (although
we still issues ioctl using old API).

And we are stuck on current termios struct, so we can't change it unless
we add compatibility symbols. Which I think it is worth only if/when 
glibc start to use termios2 internally and only for architectures that
termios does not provide all information termios2 requires (sparc and
mips basically).
  
Gabriel F. T. Gomes Nov. 9, 2018, 5:11 p.m. UTC | #4
On Fri, 09 Nov 2018, Adhemerval Zanella wrote:

>For termios we do not follow kernel userspace ABI, glibc defines both
>input and output speed in termios structure and it differs from termios
>kernel generic abi (include/uapi/asm-generic/termios.h).  In fact glibc
>follows the termios2 struct definition for most architectures (although
>we still issues ioctl using old API).
>
>And we are stuck on current termios struct, so we can't change it unless
>we add compatibility symbols. Which I think it is worth only if/when 
>glibc start to use termios2 internally and only for architectures that
>termios does not provide all information termios2 requires (sparc and
>mips basically).

Thank you so much for the explanation.
  

Patch

diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile
index ff4535cdca..184a5b19e1 100644
--- a/sysdeps/unix/sysv/linux/Makefile
+++ b/sysdeps/unix/sysv/linux/Makefile
@@ -43,7 +43,7 @@  sysdep_headers += sys/mount.h sys/acct.h sys/sysctl.h \
 		  bits/siginfo-arch.h bits/siginfo-consts-arch.h \
 		  bits/procfs.h bits/procfs-id.h bits/procfs-extra.h \
 		  bits/procfs-prregset.h bits/mman-map-flags-generic.h \
-		  bits/msq-pad.h
+		  bits/msq-pad.h bits/termios-struct.h
 
 tests += tst-clone tst-clone2 tst-clone3 tst-fanotify tst-personality \
 	 tst-quota tst-sync_file_range tst-sysconf-iov_max tst-ttyname \
diff --git a/sysdeps/unix/sysv/linux/alpha/bits/termios-struct.h b/sysdeps/unix/sysv/linux/alpha/bits/termios-struct.h
new file mode 100644
index 0000000000..268988c1a4
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/alpha/bits/termios-struct.h
@@ -0,0 +1,37 @@ 
+/* struct termios definition.  Linux/alpha version.
+   Copyright (C) 2018 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
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef _TERMIOS_H
+# error "Never include <bits/termios-struct.h> directly; use <termios.h> instead."
+#endif
+
+/* Alpha has C_CC before C_LINE compare to Linux generic definition.  */
+#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_cc[NCCS];		/* control characters */
+    cc_t c_line;		/* line discipline (== c_cc[33]) */
+    speed_t c_ispeed;		/* input speed */
+    speed_t c_ospeed;		/* output speed */
+#define _HAVE_STRUCT_TERMIOS_C_ISPEED 1
+#define _HAVE_STRUCT_TERMIOS_C_OSPEED 1
+  };
diff --git a/sysdeps/unix/sysv/linux/alpha/bits/termios.h b/sysdeps/unix/sysv/linux/alpha/bits/termios.h
index 24423e8fc9..fe358dd8f5 100644
--- a/sysdeps/unix/sysv/linux/alpha/bits/termios.h
+++ b/sysdeps/unix/sysv/linux/alpha/bits/termios.h
@@ -24,20 +24,7 @@  typedef unsigned char	cc_t;
 typedef unsigned int	speed_t;
 typedef unsigned int	tcflag_t;
 
-#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_cc[NCCS];		/* control characters */
-    cc_t c_line;		/* line discipline (== c_cc[33]) */
-    speed_t c_ispeed;		/* input speed */
-    speed_t c_ospeed;		/* output speed */
-#define _HAVE_STRUCT_TERMIOS_C_ISPEED 1
-#define _HAVE_STRUCT_TERMIOS_C_OSPEED 1
-  };
+#include <bits/termios-struct.h>
 
 /* c_cc characters */
 #define VEOF 0
diff --git a/sysdeps/unix/sysv/linux/bits/termios-struct.h b/sysdeps/unix/sysv/linux/bits/termios-struct.h
new file mode 100644
index 0000000000..ba56a547c1
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/bits/termios-struct.h
@@ -0,0 +1,36 @@ 
+/* struct termios definition.  Linux/generic version.
+   Copyright (C) 2018 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
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef _TERMIOS_H
+# error "Never include <bits/termios-struct.h> directly; use <termios.h> instead."
+#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 */
+    speed_t c_ispeed;		/* input speed */
+    speed_t c_ospeed;		/* output speed */
+#define _HAVE_STRUCT_TERMIOS_C_ISPEED 1
+#define _HAVE_STRUCT_TERMIOS_C_OSPEED 1
+  };
diff --git a/sysdeps/unix/sysv/linux/bits/termios.h b/sysdeps/unix/sysv/linux/bits/termios.h
index 1e567affc3..93536130aa 100644
--- a/sysdeps/unix/sysv/linux/bits/termios.h
+++ b/sysdeps/unix/sysv/linux/bits/termios.h
@@ -24,20 +24,7 @@  typedef unsigned char	cc_t;
 typedef unsigned int	speed_t;
 typedef unsigned int	tcflag_t;
 
-#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 */
-    speed_t c_ispeed;		/* input speed */
-    speed_t c_ospeed;		/* output speed */
-#define _HAVE_STRUCT_TERMIOS_C_ISPEED 1
-#define _HAVE_STRUCT_TERMIOS_C_OSPEED 1
-  };
+#include <bits/termios-struct.h>
 
 /* c_cc characters */
 #define VINTR 0
diff --git a/sysdeps/unix/sysv/linux/kernel_termios.h b/sysdeps/unix/sysv/linux/kernel_termios.h
index 6f505c7b61..cd000af833 100644
--- a/sysdeps/unix/sysv/linux/kernel_termios.h
+++ b/sysdeps/unix/sysv/linux/kernel_termios.h
@@ -31,4 +31,7 @@  struct __kernel_termios
     cc_t c_cc[__KERNEL_NCCS];	/* control characters */
   };
 
+#define _HAVE_C_ISPEED 0
+#define _HAVE_C_OSPEED 0
+
 #endif /* kernel_termios.h */
diff --git a/sysdeps/unix/sysv/linux/mips/bits/termios-struct.h b/sysdeps/unix/sysv/linux/mips/bits/termios-struct.h
new file mode 100644
index 0000000000..f7684e51f1
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/mips/bits/termios-struct.h
@@ -0,0 +1,34 @@ 
+/* struct termios definition.  Linux/mips version.
+   Copyright (C) 2018 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
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef _TERMIOS_H
+# error "Never include <bits/termios-struct.h> directly; use <termios.h> instead."
+#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
+  };
diff --git a/sysdeps/unix/sysv/linux/mips/bits/termios.h b/sysdeps/unix/sysv/linux/mips/bits/termios.h
index 7969144633..2b2f873f35 100644
--- a/sysdeps/unix/sysv/linux/mips/bits/termios.h
+++ b/sysdeps/unix/sysv/linux/mips/bits/termios.h
@@ -24,16 +24,7 @@  typedef unsigned char	cc_t;
 typedef unsigned int	speed_t;
 typedef unsigned int	tcflag_t;
 
-#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 */
-  };
+#include <bits/termios-struct.h>
 
 /* c_cc characters */
 #define VINTR		0	/* Interrupt character [ISIG].  */
diff --git a/sysdeps/unix/sysv/linux/mips/kernel_termios.h b/sysdeps/unix/sysv/linux/mips/kernel_termios.h
index 1c54b19428..5f88c745a0 100644
--- a/sysdeps/unix/sysv/linux/mips/kernel_termios.h
+++ b/sysdeps/unix/sysv/linux/mips/kernel_termios.h
@@ -31,4 +31,7 @@  struct __kernel_termios
     cc_t c_cc[__KERNEL_NCCS];	/* control characters */
   };
 
+#define _HAVE_C_ISPEED 0
+#define _HAVE_C_OSPEED 0
+
 #endif /* kernel_termios.h */
diff --git a/sysdeps/unix/sysv/linux/powerpc/bits/termios.h b/sysdeps/unix/sysv/linux/powerpc/bits/termios.h
index afe592d5e4..ddb32bd7e5 100644
--- a/sysdeps/unix/sysv/linux/powerpc/bits/termios.h
+++ b/sysdeps/unix/sysv/linux/powerpc/bits/termios.h
@@ -23,25 +23,7 @@  typedef unsigned char	cc_t;
 typedef unsigned int	speed_t;
 typedef unsigned int	tcflag_t;
 
-/*
- * termios type and macro definitions.  Be careful about adding stuff
- * to this file since it's used in GNU libc and there are strict rules
- * concerning namespace pollution.
- */
-
-#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 (== c_cc[19]) */
-	cc_t c_cc[NCCS];		/* control characters */
-	speed_t c_ispeed;		/* input speed */
-	speed_t c_ospeed;		/* output speed */
-#define _HAVE_STRUCT_TERMIOS_C_ISPEED 1
-#define _HAVE_STRUCT_TERMIOS_C_OSPEED 1
-};
+#include <bits/termios-struct.h>
 
 /* c_cc characters */
 #define VINTR	0
diff --git a/sysdeps/unix/sysv/linux/sparc/bits/termios-struct.h b/sysdeps/unix/sysv/linux/sparc/bits/termios-struct.h
new file mode 100644
index 0000000000..7c3489e1b9
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/sparc/bits/termios-struct.h
@@ -0,0 +1,34 @@ 
+/* struct termios definition.  Linux/sparc version.
+   Copyright (C) 2018 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
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef _TERMIOS_H
+# error "Never include <bits/termios-struct.h> directly; use <termios.h> instead."
+#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
+  };
diff --git a/sysdeps/unix/sysv/linux/sparc/bits/termios.h b/sysdeps/unix/sysv/linux/sparc/bits/termios.h
index ffe8483694..5fd6055c8e 100644
--- a/sysdeps/unix/sysv/linux/sparc/bits/termios.h
+++ b/sysdeps/unix/sysv/linux/sparc/bits/termios.h
@@ -24,16 +24,7 @@  typedef unsigned char cc_t;
 typedef unsigned int speed_t;
 typedef unsigned int tcflag_t;
 
-#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 */
-  };
+#include <bits/termios-struct.h>
 
 /* c_cc characters */
 #define VINTR    0
diff --git a/sysdeps/unix/sysv/linux/sparc/kernel_termios.h b/sysdeps/unix/sysv/linux/sparc/kernel_termios.h
index 31c717ea9d..3a27382d36 100644
--- a/sysdeps/unix/sysv/linux/sparc/kernel_termios.h
+++ b/sysdeps/unix/sysv/linux/sparc/kernel_termios.h
@@ -34,4 +34,7 @@  struct __kernel_termios
     cc_t c_cc[__KERNEL_NCCS];	/* control characters */
   };
 
+#define _HAVE_C_ISPEED 0
+#define _HAVE_C_OSPEED 0
+
 #endif /* kernel_termios.h */
diff --git a/sysdeps/unix/sysv/linux/speed.c b/sysdeps/unix/sysv/linux/speed.c
index 7db9e998c3..23834c10b5 100644
--- a/sysdeps/unix/sysv/linux/speed.c
+++ b/sysdeps/unix/sysv/linux/speed.c
@@ -58,7 +58,7 @@  cfsetospeed (struct termios *termios_p, speed_t speed)
       && (speed < B57600 || speed > __MAX_BAUD))
     return INLINE_SYSCALL_ERROR_RETURN_VALUE (EINVAL);
 
-#ifdef _HAVE_STRUCT_TERMIOS_C_OSPEED
+#if _HAVE_STRUCT_TERMIOS_C_OSPEED
   termios_p->c_ospeed = speed;
 #endif
   termios_p->c_cflag &= ~(CBAUD | CBAUDEX);
@@ -80,7 +80,7 @@  cfsetispeed (struct termios *termios_p, speed_t speed)
       && (speed < B57600 || speed > __MAX_BAUD))
     return INLINE_SYSCALL_ERROR_RETURN_VALUE (EINVAL);
 
-#ifdef _HAVE_STRUCT_TERMIOS_C_ISPEED
+#if _HAVE_STRUCT_TERMIOS_C_ISPEED
   termios_p->c_ispeed = speed;
 #endif
   if (speed == 0)
diff --git a/sysdeps/unix/sysv/linux/tcgetattr.c b/sysdeps/unix/sysv/linux/tcgetattr.c
index 9748bc8cc4..b79d9f1462 100644
--- a/sysdeps/unix/sysv/linux/tcgetattr.c
+++ b/sysdeps/unix/sysv/linux/tcgetattr.c
@@ -44,15 +44,15 @@  __tcgetattr (int fd, struct termios *termios_p)
       termios_p->c_cflag = k_termios.c_cflag;
       termios_p->c_lflag = k_termios.c_lflag;
       termios_p->c_line = k_termios.c_line;
-#ifdef _HAVE_STRUCT_TERMIOS_C_ISPEED
-# ifdef _HAVE_C_ISPEED
+#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
-#ifdef _HAVE_STRUCT_TERMIOS_C_OSPEED
-# ifdef _HAVE_C_OSPEED
+#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);
diff --git a/sysdeps/unix/sysv/linux/tcsetattr.c b/sysdeps/unix/sysv/linux/tcsetattr.c
index a916e70253..f8025a0473 100644
--- a/sysdeps/unix/sysv/linux/tcsetattr.c
+++ b/sysdeps/unix/sysv/linux/tcsetattr.c
@@ -66,10 +66,10 @@  __tcsetattr (int fd, int optional_actions, const struct termios *termios_p)
   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 defined _HAVE_C_ISPEED && defined _HAVE_STRUCT_TERMIOS_C_ISPEED
+#if _HAVE_C_ISPEED && _HAVE_STRUCT_TERMIOS_C_ISPEED
   k_termios.c_ispeed = termios_p->c_ispeed;
 #endif
-#if defined _HAVE_C_OSPEED && defined _HAVE_STRUCT_TERMIOS_C_OSPEED
+#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],