glibc/sysdeps/unix/sysv/linux/tcgetattr.c
Adhemerval Zanella e5a50db36e termios: Consolidate struct termios
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.
2019-01-03 09:32:12 -02:00

81 lines
2.5 KiB
C

/* Copyright (C) 1992-2019 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/>. */
#include <errno.h>
#include <string.h>
#include <termios.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sysdep.h>
/* 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 <kernel_termios.h>
/* Put the state of FD into *TERMIOS_P. */
int
__tcgetattr (int fd, struct termios *termios_p)
{
struct __kernel_termios k_termios;
int retval;
retval = INLINE_SYSCALL (ioctl, 3, fd, TCGETS, &k_termios);
if (__glibc_likely (retval == 0))
{
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));
for (size_t cnt = __KERNEL_NCCS; cnt < NCCS; ++cnt)
termios_p->c_cc[cnt] = _POSIX_VDISABLE;
}
}
return retval;
}
libc_hidden_def (__tcgetattr)
weak_alias (__tcgetattr, tcgetattr)