]> git.ipfire.org Git - thirdparty/glibc.git/blame - sysdeps/unix/sysv/linux/tcsetattr.c
Update copyright dates with scripts/update-copyrights.
[thirdparty/glibc.git] / sysdeps / unix / sysv / linux / tcsetattr.c
CommitLineData
688903eb 1/* Copyright (C) 1993-2018 Free Software Foundation, Inc.
df4ef2ab
UD
2 This file is part of the GNU C Library.
3
4 The GNU C Library is free software; you can redistribute it and/or
41bdb6e2
AJ
5 modify it under the terms of the GNU Lesser General Public
6 License as published by the Free Software Foundation; either
7 version 2.1 of the License, or (at your option) any later version.
df4ef2ab
UD
8
9 The GNU C Library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
41bdb6e2 12 Lesser General Public License for more details.
df4ef2ab 13
41bdb6e2 14 You should have received a copy of the GNU Lesser General Public
59ba27a6
PE
15 License along with the GNU C Library; if not, see
16 <http://www.gnu.org/licenses/>. */
df4ef2ab
UD
17
18#include <errno.h>
eb406346 19#include <string.h>
df4ef2ab
UD
20#include <termios.h>
21#include <sys/ioctl.h>
22#include <sys/types.h>
b2740a3b 23#include <sysdep.h>
df4ef2ab
UD
24
25/* The difference here is that the termios structure used in the
26 kernel is not the same as we use in the libc. Therefore we must
27 translate it here. */
5107cf1d 28#include <kernel_termios.h>
df4ef2ab
UD
29
30
a94b2ac0
UD
31/* This is a gross hack around a kernel bug. If the cfsetispeed functions
32 is called with the SPEED argument set to zero this means use the same
33 speed as for output. But we don't have independent input and output
34 speeds and therefore cannot record this.
35
36 We use an unused bit in the `c_iflag' field to keep track of this
37 use of `cfsetispeed'. The value here must correspond to the one used
38 in `speed.c'. */
eb35b097 39#define IBAUD0 020000000000
a94b2ac0
UD
40
41
df4ef2ab
UD
42/* Set the state of FD to *TERMIOS_P. */
43int
fa872e1b 44__tcsetattr (int fd, int optional_actions, const struct termios *termios_p)
df4ef2ab 45{
8d57beea 46 struct __kernel_termios k_termios;
df4ef2ab 47 unsigned long int cmd;
df4ef2ab
UD
48
49 switch (optional_actions)
50 {
51 case TCSANOW:
52 cmd = TCSETS;
53 break;
54 case TCSADRAIN:
55 cmd = TCSETSW;
56 break;
57 case TCSAFLUSH:
58 cmd = TCSETSF;
59 break;
60 default:
2caca60d 61 return INLINE_SYSCALL_ERROR_RETURN_VALUE (EINVAL);
df4ef2ab
UD
62 }
63
8c479619 64 k_termios.c_iflag = termios_p->c_iflag & ~IBAUD0;
df4ef2ab
UD
65 k_termios.c_oflag = termios_p->c_oflag;
66 k_termios.c_cflag = termios_p->c_cflag;
67 k_termios.c_lflag = termios_p->c_lflag;
68 k_termios.c_line = termios_p->c_line;
e99e0387 69#if defined _HAVE_C_ISPEED && defined _HAVE_STRUCT_TERMIOS_C_ISPEED
0c5ecdc4 70 k_termios.c_ispeed = termios_p->c_ispeed;
df4ef2ab 71#endif
e99e0387 72#if defined _HAVE_C_OSPEED && defined _HAVE_STRUCT_TERMIOS_C_OSPEED
0c5ecdc4 73 k_termios.c_ospeed = termios_p->c_ospeed;
df4ef2ab 74#endif
eb406346
UD
75 memcpy (&k_termios.c_cc[0], &termios_p->c_cc[0],
76 __KERNEL_NCCS * sizeof (cc_t));
df4ef2ab 77
e5dee2c8 78 return INLINE_SYSCALL (ioctl, 3, fd, cmd, &k_termios);
df4ef2ab 79}
fa872e1b 80weak_alias (__tcsetattr, tcsetattr)
df962917 81libc_hidden_def (tcsetattr)